1 : /******************************************************************************
2 : * $Id: ogrsqlitesqlfunctions.cpp 25462 2013-01-06 02:10:38Z rouault $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: Extension SQL functions
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 : /* WARNING: VERY IMPORTANT NOTE: This file MUST not be directly compiled as */
31 : /* a standalone object. It must be included from ogrsqlitevirtualogr.cpp */
32 : #ifndef COMPILATION_ALLOWED
33 : #error See comment in file
34 : #endif
35 :
36 : #include "ogrsqlitesqlfunctions.h"
37 : #include "ogr_geocoding.h"
38 :
39 : #include "ogrsqliteregexp.cpp" /* yes the .cpp file, to make it work on Windows with load_extension('gdalXX.dll') */
40 :
41 : #ifndef HAVE_SPATIALITE
42 : #define MINIMAL_SPATIAL_FUNCTIONS
43 : #endif
44 :
45 : class OGRSQLiteExtensionData
46 : {
47 : #ifdef DEBUG
48 : void* pDummy; /* to track memory leaks */
49 : #endif
50 : std::map< std::pair<int,int>, OGRCoordinateTransformation*> oCachedTransformsMap;
51 :
52 : void* hRegExpCache;
53 :
54 : OGRGeocodingSessionH hGeocodingSession;
55 :
56 : public:
57 : OGRSQLiteExtensionData(sqlite3* hDB);
58 : ~OGRSQLiteExtensionData();
59 :
60 : OGRCoordinateTransformation* GetTransform(int nSrcSRSId, int nDstSRSId);
61 :
62 112 : OGRGeocodingSessionH GetGeocodingSession() { return hGeocodingSession; }
63 112 : void SetGeocodingSession(OGRGeocodingSessionH hGeocodingSessionIn) { hGeocodingSession = hGeocodingSessionIn; }
64 :
65 751 : void SetRegExpCache(void* hRegExpCacheIn) { hRegExpCache = hRegExpCacheIn; }
66 : };
67 :
68 : /************************************************************************/
69 : /* OGRSQLiteExtensionData() */
70 : /************************************************************************/
71 :
72 751 : OGRSQLiteExtensionData::OGRSQLiteExtensionData(sqlite3* hDB) :
73 751 : hRegExpCache(NULL), hGeocodingSession(NULL)
74 : {
75 : #ifdef DEBUG
76 751 : pDummy = CPLMalloc(1);
77 : #endif
78 751 : }
79 :
80 : /************************************************************************/
81 : /* ~OGRSQLiteExtensionData() */
82 : /************************************************************************/
83 :
84 751 : OGRSQLiteExtensionData::~OGRSQLiteExtensionData()
85 : {
86 : #ifdef DEBUG
87 751 : CPLFree(pDummy);
88 : #endif
89 :
90 : std::map< std::pair<int,int>, OGRCoordinateTransformation*>::iterator oIter =
91 751 : oCachedTransformsMap.begin();
92 751 : for(; oIter != oCachedTransformsMap.end(); ++oIter)
93 0 : delete oIter->second;
94 :
95 751 : OGRSQLiteFreeRegExpCache(hRegExpCache);
96 :
97 751 : OGRGeocodeDestroySession(hGeocodingSession);
98 751 : }
99 :
100 : /************************************************************************/
101 : /* GetTransform() */
102 : /************************************************************************/
103 :
104 0 : OGRCoordinateTransformation* OGRSQLiteExtensionData::GetTransform(int nSrcSRSId,
105 : int nDstSRSId)
106 : {
107 : std::map< std::pair<int,int>, OGRCoordinateTransformation*>::iterator oIter =
108 0 : oCachedTransformsMap.find(std::pair<int,int>(nSrcSRSId, nDstSRSId));
109 0 : if( oIter == oCachedTransformsMap.end() )
110 : {
111 0 : OGRCoordinateTransformation* poCT = NULL;
112 0 : OGRSpatialReference oSrcSRS, oDstSRS;
113 0 : if (oSrcSRS.importFromEPSG(nSrcSRSId) == OGRERR_NONE &&
114 : oDstSRS.importFromEPSG(nDstSRSId) == OGRERR_NONE )
115 : {
116 0 : poCT = OGRCreateCoordinateTransformation( &oSrcSRS, &oDstSRS );
117 : }
118 0 : oCachedTransformsMap[std::pair<int,int>(nSrcSRSId, nDstSRSId)] = poCT;
119 0 : return poCT;
120 : }
121 : else
122 0 : return oIter->second;
123 : }
124 :
125 : /************************************************************************/
126 : /* OGR2SQLITE_ogr_version() */
127 : /************************************************************************/
128 :
129 : static
130 1 : void OGR2SQLITE_ogr_version(sqlite3_context* pContext,
131 : int argc, sqlite3_value** argv)
132 : {
133 1 : if( argc == 0 || sqlite3_value_type (argv[0]) != SQLITE_TEXT )
134 : {
135 1 : sqlite3_result_text( pContext, GDAL_RELEASE_NAME, -1, SQLITE_STATIC );
136 : }
137 : else
138 : {
139 : sqlite3_result_text( pContext,
140 : GDALVersionInfo((const char*)sqlite3_value_text(argv[0])),
141 0 : -1, SQLITE_TRANSIENT );
142 : }
143 1 : }
144 :
145 : /************************************************************************/
146 : /* OGR2SQLITE_Transform() */
147 : /************************************************************************/
148 :
149 : static
150 0 : void OGR2SQLITE_Transform(sqlite3_context* pContext,
151 : int argc, sqlite3_value** argv)
152 : {
153 0 : if( argc != 3 )
154 : {
155 0 : sqlite3_result_null (pContext);
156 0 : return;
157 : }
158 :
159 0 : if( sqlite3_value_type (argv[0]) != SQLITE_BLOB )
160 : {
161 0 : sqlite3_result_null (pContext);
162 0 : return;
163 : }
164 :
165 0 : if( sqlite3_value_type (argv[1]) != SQLITE_INTEGER )
166 : {
167 0 : sqlite3_result_null (pContext);
168 0 : return;
169 : }
170 :
171 0 : if( sqlite3_value_type (argv[2]) != SQLITE_INTEGER )
172 : {
173 0 : sqlite3_result_null (pContext);
174 0 : return;
175 : }
176 :
177 0 : int nSrcSRSId = sqlite3_value_int(argv[1]);
178 0 : int nDstSRSId = sqlite3_value_int(argv[2]);
179 :
180 : OGRSQLiteExtensionData* poModule =
181 0 : (OGRSQLiteExtensionData*) sqlite3_user_data(pContext);
182 : OGRCoordinateTransformation* poCT =
183 0 : poModule->GetTransform(nSrcSRSId, nDstSRSId);
184 0 : if( poCT == NULL )
185 : {
186 0 : sqlite3_result_null (pContext);
187 0 : return;
188 : }
189 :
190 0 : GByte* pabySLBLOB = (GByte *) sqlite3_value_blob (argv[0]);
191 0 : int nBLOBLen = sqlite3_value_bytes (argv[0]);
192 0 : OGRGeometry* poGeom = NULL;
193 0 : if( OGRSQLiteLayer::ImportSpatiaLiteGeometry(
194 : pabySLBLOB, nBLOBLen, &poGeom ) == CE_None &&
195 0 : poGeom->transform(poCT) == OGRERR_NONE &&
196 : OGRSQLiteLayer::ExportSpatiaLiteGeometry(
197 : poGeom, nDstSRSId, wkbNDR, FALSE,
198 : FALSE, FALSE, &pabySLBLOB, &nBLOBLen ) == CE_None )
199 : {
200 0 : sqlite3_result_blob(pContext, pabySLBLOB, nBLOBLen, CPLFree);
201 : }
202 : else
203 : {
204 0 : sqlite3_result_null (pContext);
205 : }
206 0 : delete poGeom;
207 : }
208 :
209 : /************************************************************************/
210 : /* OGR2SQLITE_ogr_deflate() */
211 : /************************************************************************/
212 :
213 : static
214 4 : void OGR2SQLITE_ogr_deflate(sqlite3_context* pContext,
215 : int argc, sqlite3_value** argv)
216 : {
217 4 : int nLevel = -1;
218 4 : if( !(argc == 1 || argc == 2) ||
219 : !(sqlite3_value_type (argv[0]) == SQLITE_TEXT ||
220 : sqlite3_value_type (argv[0]) == SQLITE_BLOB) )
221 : {
222 0 : sqlite3_result_null (pContext);
223 0 : return;
224 : }
225 4 : if( argc == 2 )
226 : {
227 2 : if( sqlite3_value_type (argv[1]) != SQLITE_INTEGER )
228 : {
229 1 : sqlite3_result_null (pContext);
230 1 : return;
231 : }
232 1 : nLevel = sqlite3_value_int(argv[1]);
233 : }
234 :
235 3 : size_t nOutBytes = 0;
236 : void* pOut;
237 3 : if( sqlite3_value_type (argv[0]) == SQLITE_TEXT )
238 : {
239 2 : const char* pszVal = (const char*)sqlite3_value_text(argv[0]);
240 2 : pOut = CPLZLibDeflate( pszVal, strlen(pszVal) + 1, nLevel, NULL, 0, &nOutBytes);
241 : }
242 : else
243 : {
244 1 : const void* pSrc = sqlite3_value_blob (argv[0]);
245 1 : int nLen = sqlite3_value_bytes (argv[0]);
246 1 : pOut = CPLZLibDeflate( pSrc, nLen, nLevel, NULL, 0, &nOutBytes);
247 : }
248 3 : if( pOut != NULL )
249 : {
250 3 : sqlite3_result_blob (pContext, pOut, nOutBytes, VSIFree);
251 : }
252 : else
253 : {
254 0 : sqlite3_result_null (pContext);
255 : }
256 :
257 3 : return;
258 : }
259 :
260 : /************************************************************************/
261 : /* OGR2SQLITE_ogr_inflate() */
262 : /************************************************************************/
263 :
264 : static
265 5 : void OGR2SQLITE_ogr_inflate(sqlite3_context* pContext,
266 : int argc, sqlite3_value** argv)
267 : {
268 5 : if( argc != 1 ||
269 : sqlite3_value_type (argv[0]) != SQLITE_BLOB )
270 : {
271 1 : sqlite3_result_null (pContext);
272 1 : return;
273 : }
274 :
275 4 : size_t nOutBytes = 0;
276 : void* pOut;
277 :
278 4 : const void* pSrc = sqlite3_value_blob (argv[0]);
279 4 : int nLen = sqlite3_value_bytes (argv[0]);
280 4 : pOut = CPLZLibInflate( pSrc, nLen, NULL, 0, &nOutBytes);
281 :
282 4 : if( pOut != NULL )
283 : {
284 3 : sqlite3_result_blob (pContext, pOut, nOutBytes, VSIFree);
285 : }
286 : else
287 : {
288 1 : sqlite3_result_null (pContext);
289 : }
290 :
291 4 : return;
292 : }
293 :
294 : /************************************************************************/
295 : /* OGR2SQLITE_ogr_geocode_set_result() */
296 : /************************************************************************/
297 :
298 : static
299 112 : void OGR2SQLITE_ogr_geocode_set_result(sqlite3_context* pContext,
300 : OGRLayerH hLayer,
301 : const char* pszField)
302 : {
303 112 : if( hLayer == NULL )
304 8 : sqlite3_result_null (pContext);
305 : else
306 : {
307 104 : OGRLayer* poLayer = (OGRLayer*)hLayer;
308 104 : OGRFeatureDefn* poFDefn = poLayer->GetLayerDefn();
309 104 : OGRFeature* poFeature = poLayer->GetNextFeature();
310 104 : int nIdx = -1;
311 104 : if( poFeature == NULL )
312 8 : sqlite3_result_null (pContext);
313 96 : else if( strcmp(pszField, "geometry") == 0 &&
314 : poFeature->GetGeometryRef() != NULL )
315 : {
316 32 : GByte* pabyGeomBLOB = NULL;
317 32 : int nGeomBLOBLen = 0;
318 32 : if( OGRSQLiteLayer::ExportSpatiaLiteGeometry(
319 : poFeature->GetGeometryRef(), 4326, wkbNDR, FALSE, FALSE, FALSE,
320 : &pabyGeomBLOB,
321 : &nGeomBLOBLen ) != CE_None )
322 : {
323 0 : sqlite3_result_null (pContext);
324 : }
325 : else
326 : {
327 32 : sqlite3_result_blob (pContext, pabyGeomBLOB, nGeomBLOBLen, CPLFree);
328 : }
329 : }
330 64 : else if( (nIdx = poFDefn->GetFieldIndex(pszField)) >= 0 &&
331 : poFeature->IsFieldSet(nIdx) )
332 : {
333 62 : OGRFieldType eType = poFDefn->GetFieldDefn(nIdx)->GetType();
334 62 : if( eType == OFTInteger )
335 : sqlite3_result_int(pContext,
336 0 : poFeature->GetFieldAsInteger(nIdx));
337 62 : else if( eType == OFTReal )
338 : sqlite3_result_double(pContext,
339 0 : poFeature->GetFieldAsDouble(nIdx));
340 : else
341 : sqlite3_result_text(pContext,
342 : poFeature->GetFieldAsString(nIdx),
343 62 : -1, SQLITE_TRANSIENT);
344 : }
345 : else
346 2 : sqlite3_result_null (pContext);
347 104 : delete poFeature;
348 104 : OGRGeocodeFreeResult(hLayer);
349 : }
350 112 : }
351 :
352 : /************************************************************************/
353 : /* OGR2SQLITE_ogr_geocode() */
354 : /************************************************************************/
355 :
356 : static
357 80 : void OGR2SQLITE_ogr_geocode(sqlite3_context* pContext,
358 : int argc, sqlite3_value** argv)
359 : {
360 : OGRSQLiteExtensionData* poModule =
361 80 : (OGRSQLiteExtensionData*) sqlite3_user_data(pContext);
362 :
363 80 : if( argc < 1 || sqlite3_value_type (argv[0]) != SQLITE_TEXT )
364 : {
365 16 : sqlite3_result_null (pContext);
366 16 : return;
367 : }
368 64 : const char* pszQuery = (const char*)sqlite3_value_text(argv[0]);
369 :
370 64 : CPLString osField = "geometry";
371 64 : if( argc >= 2 && sqlite3_value_type (argv[1]) == SQLITE_TEXT )
372 : {
373 32 : osField = (const char*)sqlite3_value_text(argv[1]);
374 : }
375 :
376 : int i;
377 64 : char** papszOptions = NULL;
378 72 : for(i = 2; i < argc; i++)
379 : {
380 8 : if( sqlite3_value_type (argv[i]) == SQLITE_TEXT )
381 : {
382 : papszOptions = CSLAddString(papszOptions,
383 0 : (const char*)sqlite3_value_text(argv[i]));
384 : }
385 : }
386 :
387 64 : OGRGeocodingSessionH hSession = poModule->GetGeocodingSession();
388 64 : if( hSession == NULL )
389 : {
390 64 : hSession = OGRGeocodeCreateSession(papszOptions);
391 64 : if( hSession == NULL )
392 : {
393 0 : sqlite3_result_null (pContext);
394 0 : CSLDestroy(papszOptions);
395 : return;
396 : }
397 64 : poModule->SetGeocodingSession(hSession);
398 : }
399 :
400 64 : if( osField == "raw" )
401 8 : papszOptions = CSLAddString(papszOptions, "RAW_FEATURE=YES");
402 :
403 64 : if( CSLFindString(papszOptions, "LIMIT") == -1 )
404 64 : papszOptions = CSLAddString(papszOptions, "LIMIT=1");
405 :
406 64 : OGRLayerH hLayer = OGRGeocode(hSession, pszQuery, NULL, papszOptions);
407 :
408 64 : OGR2SQLITE_ogr_geocode_set_result(pContext, hLayer, osField);
409 :
410 64 : CSLDestroy(papszOptions);
411 :
412 0 : return;
413 : }
414 :
415 : /************************************************************************/
416 : /* OGR2SQLITE_GetValAsDouble() */
417 : /************************************************************************/
418 :
419 144 : static double OGR2SQLITE_GetValAsDouble(sqlite3_value* val, int* pbGotVal)
420 : {
421 144 : switch(sqlite3_value_type(val))
422 : {
423 : case SQLITE_FLOAT:
424 32 : if( pbGotVal ) *pbGotVal = TRUE;
425 32 : return sqlite3_value_double(val);
426 :
427 : case SQLITE_INTEGER:
428 64 : if( pbGotVal ) *pbGotVal = TRUE;
429 64 : return sqlite3_value_int64(val);
430 :
431 : default:
432 48 : if( pbGotVal ) *pbGotVal = FALSE;
433 48 : return 0.0;
434 : }
435 : }
436 :
437 : /************************************************************************/
438 : /* OGR2SQLITE_GetGeom() */
439 : /************************************************************************/
440 :
441 16 : static OGRGeometry* OGR2SQLITE_GetGeom(sqlite3_context* pContext,
442 : int argc, sqlite3_value** argv,
443 : int* pnSRSId)
444 : {
445 16 : if( sqlite3_value_type (argv[0]) != SQLITE_BLOB )
446 : {
447 0 : return NULL;
448 : }
449 :
450 16 : GByte* pabySLBLOB = (GByte *) sqlite3_value_blob (argv[0]);
451 16 : int nBLOBLen = sqlite3_value_bytes (argv[0]);
452 16 : OGRGeometry* poGeom = NULL;
453 16 : if( OGRSQLiteLayer::ImportSpatiaLiteGeometry(
454 : pabySLBLOB, nBLOBLen, &poGeom, pnSRSId) != CE_None )
455 : {
456 0 : return NULL;
457 : }
458 :
459 16 : return poGeom;
460 : }
461 :
462 : /************************************************************************/
463 : /* OGR2SQLITE_ogr_geocode_reverse() */
464 : /************************************************************************/
465 :
466 : static
467 96 : void OGR2SQLITE_ogr_geocode_reverse(sqlite3_context* pContext,
468 : int argc, sqlite3_value** argv)
469 : {
470 : OGRSQLiteExtensionData* poModule =
471 96 : (OGRSQLiteExtensionData*) sqlite3_user_data(pContext);
472 :
473 96 : double dfLon = 0.0, dfLat = 0.0;
474 96 : int iAfterGeomIdx = 0;
475 96 : int bGotLon = FALSE, bGotLat = FALSE;
476 :
477 96 : if( argc >= 2 )
478 : {
479 72 : dfLon = OGR2SQLITE_GetValAsDouble(argv[0], &bGotLon);
480 72 : dfLat = OGR2SQLITE_GetValAsDouble(argv[1], &bGotLat);
481 : }
482 :
483 96 : if( argc >= 3 && bGotLon && bGotLat &&
484 : sqlite3_value_type (argv[2]) == SQLITE_TEXT )
485 : {
486 32 : iAfterGeomIdx = 2;
487 : }
488 64 : else if( argc >= 2 &&
489 : sqlite3_value_type (argv[0]) == SQLITE_BLOB &&
490 : sqlite3_value_type (argv[1]) == SQLITE_TEXT )
491 : {
492 16 : OGRGeometry* poGeom = OGR2SQLITE_GetGeom(pContext, argc, argv, NULL);
493 16 : if( poGeom != NULL && wkbFlatten(poGeom->getGeometryType()) == wkbPoint )
494 : {
495 16 : OGRPoint* poPoint = (OGRPoint*) poGeom;
496 16 : dfLon = poPoint->getX();
497 16 : dfLat = poPoint->getY();
498 16 : delete poGeom;
499 : }
500 : else
501 : {
502 0 : delete poGeom;
503 0 : sqlite3_result_null (pContext);
504 0 : return;
505 : }
506 16 : iAfterGeomIdx = 1;
507 : }
508 : else
509 : {
510 48 : sqlite3_result_null (pContext);
511 48 : return;
512 : }
513 :
514 48 : const char* pszField = (const char*)sqlite3_value_text(argv[iAfterGeomIdx]);
515 :
516 : int i;
517 48 : char** papszOptions = NULL;
518 64 : for(i = iAfterGeomIdx + 1; i < argc; i++)
519 : {
520 16 : if( sqlite3_value_type (argv[i]) == SQLITE_TEXT )
521 : {
522 : papszOptions = CSLAddString(papszOptions,
523 16 : (const char*)sqlite3_value_text(argv[i]));
524 : }
525 : }
526 :
527 48 : OGRGeocodingSessionH hSession = poModule->GetGeocodingSession();
528 48 : if( hSession == NULL )
529 : {
530 48 : hSession = OGRGeocodeCreateSession(papszOptions);
531 48 : if( hSession == NULL )
532 : {
533 0 : sqlite3_result_null (pContext);
534 0 : CSLDestroy(papszOptions);
535 0 : return;
536 : }
537 48 : poModule->SetGeocodingSession(hSession);
538 : }
539 :
540 48 : if( strcmp(pszField, "raw") == 0 )
541 8 : papszOptions = CSLAddString(papszOptions, "RAW_FEATURE=YES");
542 :
543 48 : OGRLayerH hLayer = OGRGeocodeReverse(hSession, dfLon, dfLat, papszOptions);
544 :
545 48 : OGR2SQLITE_ogr_geocode_set_result(pContext, hLayer, pszField);
546 :
547 48 : CSLDestroy(papszOptions);
548 :
549 48 : return;
550 : }
551 :
552 : /************************************************************************/
553 : /* OGR2SQLITE_ogr_datasource_load_layers() */
554 : /************************************************************************/
555 :
556 : static
557 8 : void OGR2SQLITE_ogr_datasource_load_layers(sqlite3_context* pContext,
558 : int argc, sqlite3_value** argv)
559 : {
560 8 : sqlite3* hDB = (sqlite3*) sqlite3_user_data(pContext);
561 :
562 8 : if( (argc < 1 || argc > 3) || sqlite3_value_type (argv[0]) != SQLITE_TEXT )
563 : {
564 1 : sqlite3_result_int (pContext, 0);
565 1 : return;
566 : }
567 7 : const char* pszDataSource = (const char*) sqlite3_value_text(argv[0]);
568 :
569 7 : int bUpdate = FALSE;
570 7 : if( argc >= 2 )
571 : {
572 4 : if( sqlite3_value_type(argv[1]) != SQLITE_INTEGER )
573 : {
574 1 : sqlite3_result_int (pContext, 0);
575 1 : return;
576 : }
577 3 : bUpdate = sqlite3_value_int(argv[1]);
578 : }
579 :
580 6 : const char* pszPrefix = NULL;
581 6 : if( argc >= 3 )
582 : {
583 2 : if( sqlite3_value_type(argv[2]) != SQLITE_TEXT )
584 : {
585 1 : sqlite3_result_int (pContext, 0);
586 1 : return;
587 : }
588 1 : pszPrefix = (const char*) sqlite3_value_text(argv[2]);
589 : }
590 :
591 5 : OGRDataSource* poDS = (OGRDataSource*)OGROpenShared(pszDataSource, bUpdate, NULL);
592 5 : if( poDS == NULL )
593 : {
594 1 : CPLError(CE_Failure, CPLE_AppDefined, "Cannot open %s", pszDataSource);
595 1 : sqlite3_result_int (pContext, 0);
596 1 : return;
597 : }
598 :
599 4 : CPLString osEscapedDataSource = OGRSQLiteEscape(pszDataSource);
600 8 : for(int i=0;i<poDS->GetLayerCount();i++)
601 : {
602 4 : const char* pszLayerName = poDS->GetLayer(i)->GetName();
603 4 : CPLString osEscapedLayerName = OGRSQLiteEscape(pszLayerName);
604 4 : CPLString osTableName;
605 4 : if( pszPrefix != NULL )
606 : {
607 1 : osTableName = pszPrefix;
608 1 : osTableName += "_";
609 1 : osTableName += OGRSQLiteEscapeName(pszLayerName);
610 : }
611 : else
612 : {
613 3 : osTableName = OGRSQLiteEscapeName(pszLayerName);
614 : }
615 :
616 4 : char* pszErrMsg = NULL;
617 4 : if( sqlite3_exec(hDB, CPLSPrintf(
618 : "CREATE VIRTUAL TABLE \"%s\" USING VirtualOGR('%s', %d, '%s')",
619 : osTableName.c_str(),
620 : osEscapedDataSource.c_str(),
621 : bUpdate,
622 : osEscapedLayerName.c_str()),
623 : NULL, NULL, &pszErrMsg) != SQLITE_OK )
624 : {
625 : CPLError(CE_Failure, CPLE_AppDefined,
626 : "Cannot create table \"%s\" : %s",
627 1 : osTableName.c_str(), pszErrMsg);
628 1 : sqlite3_free(pszErrMsg);
629 : }
630 : }
631 :
632 4 : poDS->Release();
633 4 : sqlite3_result_int (pContext, 1);
634 : }
635 :
636 : #ifdef notdef
637 : /************************************************************************/
638 : /* OGR2SQLITE_ogr_GetConfigOption() */
639 : /************************************************************************/
640 :
641 : static
642 : void OGR2SQLITE_ogr_GetConfigOption(sqlite3_context* pContext,
643 : int argc, sqlite3_value** argv)
644 : {
645 : if( sqlite3_value_type (argv[0]) != SQLITE_TEXT )
646 : {
647 : sqlite3_result_null (pContext);
648 : return;
649 : }
650 :
651 : const char* pszKey = (const char*)sqlite3_value_text(argv[0]);
652 : const char* pszVal = CPLGetConfigOption(pszKey, NULL);
653 : if( pszVal == NULL )
654 : sqlite3_result_null (pContext);
655 : else
656 : sqlite3_result_text( pContext, pszVal, -1, SQLITE_TRANSIENT );
657 : }
658 :
659 : /************************************************************************/
660 : /* OGR2SQLITE_ogr_SetConfigOption() */
661 : /************************************************************************/
662 :
663 : static
664 : void OGR2SQLITE_ogr_SetConfigOption(sqlite3_context* pContext,
665 : int argc, sqlite3_value** argv)
666 : {
667 : if( sqlite3_value_type (argv[0]) != SQLITE_TEXT )
668 : {
669 : sqlite3_result_null (pContext);
670 : return;
671 : }
672 : if( sqlite3_value_type (argv[1]) != SQLITE_TEXT &&
673 : sqlite3_value_type (argv[1]) != SQLITE_NULL )
674 : {
675 : sqlite3_result_null (pContext);
676 : return;
677 : }
678 :
679 : const char* pszKey = (const char*)sqlite3_value_text(argv[0]);
680 : const char* pszVal = (sqlite3_value_type (argv[1]) == SQLITE_TEXT) ?
681 : (const char*)sqlite3_value_text(argv[1]) : NULL;
682 : CPLSetConfigOption(pszKey, pszVal);
683 : sqlite3_result_null (pContext);
684 : }
685 : #endif // notdef
686 :
687 : #ifdef MINIMAL_SPATIAL_FUNCTIONS
688 :
689 : /************************************************************************/
690 : /* OGR2SQLITE_ST_AsText() */
691 : /************************************************************************/
692 :
693 : static
694 : void OGR2SQLITE_ST_AsText(sqlite3_context* pContext,
695 : int argc, sqlite3_value** argv)
696 : {
697 : OGRGeometry* poGeom = OGR2SQLITE_GetGeom(pContext, argc, argv, NULL);
698 : if( poGeom != NULL )
699 : {
700 : char* pszWKT = NULL;
701 : if( poGeom->exportToWkt(&pszWKT) == OGRERR_NONE )
702 : sqlite3_result_text( pContext, pszWKT, -1, CPLFree);
703 : else
704 : sqlite3_result_null (pContext);
705 : delete poGeom;
706 : }
707 : else
708 : sqlite3_result_null (pContext);
709 : }
710 :
711 : /************************************************************************/
712 : /* OGR2SQLITE_ST_AsBinary() */
713 : /************************************************************************/
714 :
715 : static
716 : void OGR2SQLITE_ST_AsBinary(sqlite3_context* pContext,
717 : int argc, sqlite3_value** argv)
718 : {
719 : OGRGeometry* poGeom = OGR2SQLITE_GetGeom(pContext, argc, argv, NULL);
720 : if( poGeom != NULL )
721 : {
722 : int nBLOBLen = poGeom->WkbSize();
723 : GByte* pabyGeomBLOB = (GByte*) VSIMalloc(nBLOBLen);
724 : if( pabyGeomBLOB != NULL )
725 : {
726 : if( poGeom->exportToWkb(wkbNDR, pabyGeomBLOB) == OGRERR_NONE )
727 : sqlite3_result_blob( pContext, pabyGeomBLOB, nBLOBLen, CPLFree);
728 : else
729 : {
730 : VSIFree(pabyGeomBLOB);
731 : sqlite3_result_null (pContext);
732 : }
733 : }
734 : else
735 : sqlite3_result_null (pContext);
736 : delete poGeom;
737 : }
738 : else
739 : sqlite3_result_null (pContext);
740 : }
741 :
742 : /************************************************************************/
743 : /* OGR2SQLITE_SetGeom_AndDestroy() */
744 : /************************************************************************/
745 :
746 : static void OGR2SQLITE_SetGeom_AndDestroy(sqlite3_context* pContext,
747 : OGRGeometry* poGeom,
748 : int nSRSId)
749 : {
750 : GByte* pabySLBLOB = NULL;
751 : int nBLOBLen = 0;
752 : if( poGeom != NULL && OGRSQLiteLayer::ExportSpatiaLiteGeometry(
753 : poGeom, nSRSId, wkbNDR, FALSE,
754 : FALSE, FALSE, &pabySLBLOB, &nBLOBLen ) == CE_None )
755 : {
756 : sqlite3_result_blob(pContext, pabySLBLOB, nBLOBLen, CPLFree);
757 : }
758 : else
759 : {
760 : sqlite3_result_null(pContext);
761 : }
762 : delete poGeom;
763 : }
764 :
765 : /************************************************************************/
766 : /* OGR2SQLITE_ST_GeomFromText() */
767 : /************************************************************************/
768 :
769 : static
770 : void OGR2SQLITE_ST_GeomFromText(sqlite3_context* pContext,
771 : int argc, sqlite3_value** argv)
772 : {
773 : if( sqlite3_value_type (argv[0]) != SQLITE_TEXT )
774 : {
775 : sqlite3_result_null (pContext);
776 : return;
777 : }
778 : char* pszWKT = (char*) sqlite3_value_text( argv[0] );
779 :
780 : int nSRID = -1;
781 : if( argc == 2 && sqlite3_value_type (argv[1]) == SQLITE_INTEGER )
782 : nSRID = sqlite3_value_int( argv[1] );
783 :
784 : OGRGeometry* poGeom = NULL;
785 : if( OGRGeometryFactory::createFromWkt(&pszWKT, NULL, &poGeom) == OGRERR_NONE )
786 : {
787 : OGR2SQLITE_SetGeom_AndDestroy(pContext, poGeom, nSRID);
788 : }
789 : else
790 : sqlite3_result_null (pContext);
791 : }
792 :
793 : /************************************************************************/
794 : /* OGR2SQLITE_ST_GeomFromWKB() */
795 : /************************************************************************/
796 :
797 : static
798 : void OGR2SQLITE_ST_GeomFromWKB(sqlite3_context* pContext,
799 : int argc, sqlite3_value** argv)
800 : {
801 : if( sqlite3_value_type (argv[0]) != SQLITE_BLOB )
802 : {
803 : sqlite3_result_null (pContext);
804 : return;
805 : }
806 :
807 : int nSRID = -1;
808 : if( argc == 2 && sqlite3_value_type (argv[1]) == SQLITE_INTEGER )
809 : nSRID = sqlite3_value_int( argv[1] );
810 :
811 : GByte* pabySLBLOB = (GByte *) sqlite3_value_blob (argv[0]);
812 : int nBLOBLen = sqlite3_value_bytes (argv[0]);
813 : OGRGeometry* poGeom = NULL;
814 :
815 : if( OGRGeometryFactory::createFromWkb(pabySLBLOB, NULL, &poGeom, nBLOBLen)
816 : == OGRERR_NONE )
817 : {
818 : OGR2SQLITE_SetGeom_AndDestroy(pContext, poGeom, nSRID);
819 : }
820 : else
821 : sqlite3_result_null (pContext);
822 : }
823 :
824 : /************************************************************************/
825 : /* CheckSTFunctions() */
826 : /************************************************************************/
827 :
828 : static int CheckSTFunctions(sqlite3_context* pContext,
829 : int argc, sqlite3_value** argv,
830 : OGRGeometry** ppoGeom1,
831 : OGRGeometry** ppoGeom2,
832 : int *pnSRSId )
833 : {
834 : *ppoGeom1 = NULL;
835 : *ppoGeom2 = NULL;
836 :
837 : if( argc != 2)
838 : {
839 : return FALSE;
840 : }
841 :
842 : *ppoGeom1 = OGR2SQLITE_GetGeom(pContext, argc, argv, pnSRSId);
843 : if( *ppoGeom1 == NULL )
844 : return FALSE;
845 :
846 : *ppoGeom2 = OGR2SQLITE_GetGeom(pContext, argc - 1, argv + 1, NULL);
847 : if( *ppoGeom2 == NULL )
848 : {
849 : delete *ppoGeom1;
850 : *ppoGeom1 = NULL;
851 : return FALSE;
852 : }
853 :
854 : return TRUE;
855 : }
856 :
857 : /************************************************************************/
858 : /* OGR2SQLITE_ST_int_geomgeom_op() */
859 : /************************************************************************/
860 :
861 : #define OGR2SQLITE_ST_int_geomgeom_op(op) \
862 : static \
863 : void OGR2SQLITE_ST_##op (sqlite3_context* pContext, \
864 : int argc, sqlite3_value** argv) \
865 : { \
866 : OGRGeometry* poGeom1 = NULL; \
867 : OGRGeometry* poGeom2 = NULL; \
868 : if( !CheckSTFunctions(pContext, argc, argv, &poGeom1, &poGeom2, NULL) ) \
869 : { \
870 : sqlite3_result_int(pContext, 0); \
871 : return; \
872 : } \
873 : \
874 : sqlite3_result_int( pContext, poGeom1-> op (poGeom2) ); \
875 : \
876 : delete poGeom1; \
877 : delete poGeom2; \
878 : }
879 :
880 : OGR2SQLITE_ST_int_geomgeom_op(Intersects)
881 : OGR2SQLITE_ST_int_geomgeom_op(Equals)
882 : OGR2SQLITE_ST_int_geomgeom_op(Disjoint)
883 : OGR2SQLITE_ST_int_geomgeom_op(Touches)
884 : OGR2SQLITE_ST_int_geomgeom_op(Crosses)
885 : OGR2SQLITE_ST_int_geomgeom_op(Within)
886 : OGR2SQLITE_ST_int_geomgeom_op(Contains)
887 : OGR2SQLITE_ST_int_geomgeom_op(Overlaps)
888 :
889 : /************************************************************************/
890 : /* OGR2SQLITE_ST_int_geom_op() */
891 : /************************************************************************/
892 :
893 : #define OGR2SQLITE_ST_int_geom_op(op) \
894 : static \
895 : void OGR2SQLITE_ST_##op (sqlite3_context* pContext, \
896 : int argc, sqlite3_value** argv) \
897 : { \
898 : OGRGeometry* poGeom = OGR2SQLITE_GetGeom(pContext, argc, argv, NULL); \
899 : if( poGeom != NULL ) \
900 : sqlite3_result_int( pContext, poGeom-> op () ); \
901 : else \
902 : sqlite3_result_int( pContext, 0 ); \
903 : \
904 : delete poGeom; \
905 : }
906 :
907 : OGR2SQLITE_ST_int_geom_op(IsEmpty)
908 : OGR2SQLITE_ST_int_geom_op(IsSimple)
909 : OGR2SQLITE_ST_int_geom_op(IsValid)
910 :
911 : /************************************************************************/
912 : /* OGR2SQLITE_ST_geom_geomgeom_op() */
913 : /************************************************************************/
914 :
915 : #define OGR2SQLITE_ST_geom_geomgeom_op(op) \
916 : static \
917 : void OGR2SQLITE_ST_##op (sqlite3_context* pContext, \
918 : int argc, sqlite3_value** argv) \
919 : { \
920 : OGRGeometry* poGeom1 = NULL; \
921 : OGRGeometry* poGeom2 = NULL; \
922 : int nSRSId = -1; \
923 : if( !CheckSTFunctions(pContext, argc, argv, &poGeom1, &poGeom2, &nSRSId) ) \
924 : { \
925 : sqlite3_result_null(pContext); \
926 : return; \
927 : } \
928 : \
929 : OGR2SQLITE_SetGeom_AndDestroy(pContext, \
930 : poGeom1-> op (poGeom2), \
931 : nSRSId); \
932 : \
933 : delete poGeom1; \
934 : delete poGeom2; \
935 : }
936 :
937 : OGR2SQLITE_ST_geom_geomgeom_op(Intersection)
938 : OGR2SQLITE_ST_geom_geomgeom_op(Difference)
939 : OGR2SQLITE_ST_geom_geomgeom_op(Union)
940 : OGR2SQLITE_ST_geom_geomgeom_op(SymDifference)
941 :
942 : /************************************************************************/
943 : /* OGR2SQLITE_ST_SRID() */
944 : /************************************************************************/
945 :
946 : static
947 : void OGR2SQLITE_ST_SRID(sqlite3_context* pContext,
948 : int argc, sqlite3_value** argv)
949 : {
950 : int nSRSId = -1;
951 : OGRGeometry* poGeom = OGR2SQLITE_GetGeom(pContext, argc, argv, &nSRSId);
952 : if( poGeom != NULL )
953 : {
954 : CPLPushErrorHandler(CPLQuietErrorHandler);
955 : sqlite3_result_int( pContext, nSRSId );
956 : CPLPopErrorHandler();
957 : }
958 : else
959 : sqlite3_result_null(pContext);
960 : delete poGeom;
961 : }
962 :
963 : /************************************************************************/
964 : /* OGR2SQLITE_ST_Area() */
965 : /************************************************************************/
966 :
967 : static
968 : void OGR2SQLITE_ST_Area(sqlite3_context* pContext,
969 : int argc, sqlite3_value** argv)
970 : {
971 : OGRGeometry* poGeom = OGR2SQLITE_GetGeom(pContext, argc, argv, NULL);
972 : if( poGeom != NULL )
973 : {
974 : CPLPushErrorHandler(CPLQuietErrorHandler);
975 : sqlite3_result_double( pContext, OGR_G_Area((OGRGeometryH)poGeom) );
976 : CPLPopErrorHandler();
977 : }
978 : else
979 : sqlite3_result_null(pContext);
980 : delete poGeom;
981 : }
982 :
983 : /************************************************************************/
984 : /* OGR2SQLITE_ST_Buffer() */
985 : /************************************************************************/
986 :
987 : static
988 : void OGR2SQLITE_ST_Buffer(sqlite3_context* pContext,
989 : int argc, sqlite3_value** argv)
990 : {
991 : int nSRSId = -1;
992 : OGRGeometry* poGeom = OGR2SQLITE_GetGeom(pContext, argc, argv, &nSRSId);
993 : int bGotVal;
994 : double dfDist = OGR2SQLITE_GetValAsDouble(argv[1], &bGotVal);
995 : if( poGeom != NULL && bGotVal )
996 : OGR2SQLITE_SetGeom_AndDestroy(pContext, poGeom->Buffer(dfDist), nSRSId);
997 : else
998 : sqlite3_result_null(pContext);
999 : delete poGeom;
1000 : }
1001 :
1002 : /************************************************************************/
1003 : /* OGR2SQLITE_ST_MakePoint() */
1004 : /************************************************************************/
1005 :
1006 : static
1007 : void OGR2SQLITE_ST_MakePoint(sqlite3_context* pContext,
1008 : int argc, sqlite3_value** argv)
1009 : {
1010 : double dfX, dfY = 0.0;
1011 : int bGotVal;
1012 : dfX = OGR2SQLITE_GetValAsDouble(argv[0], &bGotVal);
1013 : if( bGotVal )
1014 : dfY = OGR2SQLITE_GetValAsDouble(argv[1], &bGotVal);
1015 : if( !bGotVal )
1016 : {
1017 : sqlite3_result_null(pContext);
1018 : return;
1019 : }
1020 :
1021 : OGRPoint* poPoint;
1022 : if( argc == 3 )
1023 : {
1024 : double dfZ = OGR2SQLITE_GetValAsDouble(argv[2], &bGotVal);
1025 : if( !bGotVal )
1026 : {
1027 : sqlite3_result_null(pContext);
1028 : return;
1029 : }
1030 :
1031 : poPoint = new OGRPoint(dfX, dfY, dfZ);
1032 : }
1033 : else
1034 : poPoint = new OGRPoint(dfX, dfY);
1035 :
1036 : OGR2SQLITE_SetGeom_AndDestroy(pContext, poPoint, -1);
1037 : }
1038 :
1039 : #endif // #ifdef MINIMAL_SPATIAL_FUNCTIONS
1040 :
1041 : /************************************************************************/
1042 : /* OGRSQLiteRegisterSQLFunctions() */
1043 : /************************************************************************/
1044 :
1045 : static
1046 751 : void* OGRSQLiteRegisterSQLFunctions(sqlite3* hDB)
1047 : {
1048 751 : OGRSQLiteExtensionData* pData = new OGRSQLiteExtensionData(hDB);
1049 :
1050 : sqlite3_create_function(hDB, "ogr_version", 0, SQLITE_ANY, NULL,
1051 751 : OGR2SQLITE_ogr_version, NULL, NULL);
1052 :
1053 : sqlite3_create_function(hDB, "ogr_version", 1, SQLITE_ANY, NULL,
1054 751 : OGR2SQLITE_ogr_version, NULL, NULL);
1055 :
1056 : sqlite3_create_function(hDB, "ogr_deflate", 1, SQLITE_ANY, NULL,
1057 751 : OGR2SQLITE_ogr_deflate, NULL, NULL);
1058 :
1059 : sqlite3_create_function(hDB, "ogr_deflate", 2, SQLITE_ANY, NULL,
1060 751 : OGR2SQLITE_ogr_deflate, NULL, NULL);
1061 :
1062 : sqlite3_create_function(hDB, "ogr_inflate", 1, SQLITE_ANY, NULL,
1063 751 : OGR2SQLITE_ogr_inflate, NULL, NULL);
1064 :
1065 : sqlite3_create_function(hDB, "ogr_geocode", -1, SQLITE_ANY, pData,
1066 751 : OGR2SQLITE_ogr_geocode, NULL, NULL);
1067 :
1068 : sqlite3_create_function(hDB, "ogr_geocode_reverse", -1, SQLITE_ANY, pData,
1069 751 : OGR2SQLITE_ogr_geocode_reverse, NULL, NULL);
1070 :
1071 : sqlite3_create_function(hDB, "ogr_datasource_load_layers", 1, SQLITE_ANY, hDB,
1072 751 : OGR2SQLITE_ogr_datasource_load_layers, NULL, NULL);
1073 :
1074 : sqlite3_create_function(hDB, "ogr_datasource_load_layers", 2, SQLITE_ANY, hDB,
1075 751 : OGR2SQLITE_ogr_datasource_load_layers, NULL, NULL);
1076 :
1077 : sqlite3_create_function(hDB, "ogr_datasource_load_layers", 3, SQLITE_ANY, hDB,
1078 751 : OGR2SQLITE_ogr_datasource_load_layers, NULL, NULL);
1079 :
1080 : #if notdef
1081 : sqlite3_create_function(hDB, "ogr_GetConfigOption", 1, SQLITE_ANY, NULL,
1082 : OGR2SQLITE_ogr_GetConfigOption, NULL, NULL);
1083 :
1084 : sqlite3_create_function(hDB, "ogr_SetConfigOption", 2, SQLITE_ANY, NULL,
1085 : OGR2SQLITE_ogr_SetConfigOption, NULL, NULL);
1086 : #endif
1087 :
1088 : // Custom and undocumented function, not sure I'll keep it.
1089 : sqlite3_create_function(hDB, "Transform3", 3, SQLITE_ANY, pData,
1090 751 : OGR2SQLITE_Transform, NULL, NULL);
1091 :
1092 : #ifdef MINIMAL_SPATIAL_FUNCTIONS
1093 : /* Check if spatialite is available */
1094 : int rc = sqlite3_exec(hDB, "SELECT spatialite_version()", NULL, NULL, NULL);
1095 :
1096 : /* Reset error flag */
1097 : sqlite3_exec(hDB, "SELECT 1", NULL, NULL, NULL);
1098 :
1099 : if( rc != SQLITE_OK &&
1100 : CSLTestBoolean(CPLGetConfigOption("OGR_SQLITE_SPATIAL_FUNCTIONS", "YES")) )
1101 : {
1102 : CPLDebug("SQLITE",
1103 : "Spatialite not available. Implementing a few functions");
1104 :
1105 : #define REGISTER_ST_op(argc, op) \
1106 : sqlite3_create_function(hDB, #op, argc, SQLITE_ANY, NULL, \
1107 : OGR2SQLITE_ST_##op, NULL, NULL); \
1108 : sqlite3_create_function(hDB, "ST_" #op, argc, SQLITE_ANY, NULL, \
1109 : OGR2SQLITE_ST_##op, NULL, NULL);
1110 :
1111 : REGISTER_ST_op(1, AsText);
1112 : REGISTER_ST_op(1, AsBinary);
1113 : REGISTER_ST_op(1, GeomFromText);
1114 : REGISTER_ST_op(2, GeomFromText);
1115 : REGISTER_ST_op(1, GeomFromWKB);
1116 : REGISTER_ST_op(2, GeomFromWKB);
1117 :
1118 : REGISTER_ST_op(1, IsEmpty);
1119 : REGISTER_ST_op(1, IsSimple);
1120 : REGISTER_ST_op(1, IsValid);
1121 :
1122 : REGISTER_ST_op(2, Intersects);
1123 : REGISTER_ST_op(2, Equals);
1124 : REGISTER_ST_op(2, Disjoint);
1125 : REGISTER_ST_op(2, Touches);
1126 : REGISTER_ST_op(2, Crosses);
1127 : REGISTER_ST_op(2, Within);
1128 : REGISTER_ST_op(2, Contains);
1129 : REGISTER_ST_op(2, Overlaps);
1130 :
1131 : REGISTER_ST_op(2, Intersection);
1132 : REGISTER_ST_op(2, Difference);
1133 : // Union() is invalid
1134 : sqlite3_create_function(hDB, "ST_Union", 2, SQLITE_ANY, NULL,
1135 : OGR2SQLITE_ST_Union, NULL, NULL);
1136 : REGISTER_ST_op(2, SymDifference);
1137 :
1138 : REGISTER_ST_op(1, SRID);
1139 : REGISTER_ST_op(1, Area);
1140 : REGISTER_ST_op(2, Buffer);
1141 : REGISTER_ST_op(2, MakePoint);
1142 : REGISTER_ST_op(3, MakePoint);
1143 : }
1144 : #endif // #ifdef MINIMAL_SPATIAL_FUNCTIONS
1145 :
1146 751 : pData->SetRegExpCache(OGRSQLiteRegisterRegExpFunction(hDB));
1147 :
1148 751 : return pData;
1149 : }
1150 :
1151 : /************************************************************************/
1152 : /* OGRSQLiteUnregisterSQLFunctions() */
1153 : /************************************************************************/
1154 :
1155 : static
1156 751 : void OGRSQLiteUnregisterSQLFunctions(void* hHandle)
1157 : {
1158 751 : OGRSQLiteExtensionData* pData = (OGRSQLiteExtensionData* )hHandle;
1159 751 : delete pData;
1160 751 : }
|