Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: OpenGIS Simple Features Reference Implementation
4 : * Purpose: Definition of classes and functions used by SQLite and GPKG drivers
5 : * Author: Even Rouault <even dot rouault at spatialys.com>
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2021, Even Rouault <even dot rouault at spatialys.com>
9 : *
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #ifndef OGR_SQLITE_BASE_H_INCLUDED
14 : #define OGR_SQLITE_BASE_H_INCLUDED
15 :
16 : #include "cpl_vsi.h"
17 : #include "cpl_string.h"
18 : #include "gdal_pam.h"
19 : #include "ogrsf_frmts.h"
20 :
21 : #include <sqlite3.h>
22 :
23 : // to avoid -Wold-style-cast with some compilers
24 : #undef SQLITE_TRANSIENT
25 : #define SQLITE_TRANSIENT reinterpret_cast<sqlite3_destructor_type>(-1)
26 :
27 : #include <map>
28 : #include <utility>
29 : #include <vector>
30 :
31 : /************************************************************************/
32 : /* Format used to store geometry data in the database. */
33 : /************************************************************************/
34 :
35 : enum OGRSQLiteGeomFormat
36 : {
37 : OSGF_None = 0,
38 : OSGF_WKT = 1,
39 : OSGF_WKB = 2,
40 : OSGF_FGF = 3,
41 : OSGF_SpatiaLite = 4
42 : };
43 :
44 : /************************************************************************/
45 : /* OGRSQLiteGeomFieldDefn */
46 : /************************************************************************/
47 :
48 1816 : class OGRSQLiteGeomFieldDefn final : public OGRGeomFieldDefn
49 : {
50 : public:
51 908 : OGRSQLiteGeomFieldDefn(const char *pszNameIn, int iGeomColIn)
52 908 : : OGRGeomFieldDefn(pszNameIn, wkbUnknown), m_iCol(iGeomColIn)
53 : {
54 908 : }
55 :
56 : ~OGRSQLiteGeomFieldDefn() override;
57 :
58 : int m_nSRSId = -1;
59 : int m_iCol; /* ordinal of geometry field in SQL statement */
60 : bool m_bTriedAsSpatiaLite = false;
61 : OGRSQLiteGeomFormat m_eGeomFormat = OSGF_None;
62 : OGREnvelope m_oCachedExtent{};
63 : bool m_bCachedExtentIsValid = false;
64 : bool m_bHasSpatialIndex = false;
65 : bool m_bHasCheckedSpatialIndexTable = false;
66 : std::vector<std::pair<CPLString, CPLString>> m_aosDisabledTriggers{};
67 : };
68 :
69 : /************************************************************************/
70 : /* OGRSQLiteFeatureDefn */
71 : /************************************************************************/
72 :
73 7296 : class OGRSQLiteFeatureDefn final : public OGRFeatureDefn
74 : {
75 : public:
76 3648 : explicit OGRSQLiteFeatureDefn(const char *pszName = nullptr)
77 3648 : : OGRFeatureDefn(pszName)
78 : {
79 3648 : SetGeomType(wkbNone);
80 3648 : }
81 :
82 : ~OGRSQLiteFeatureDefn() override;
83 :
84 27875 : OGRSQLiteGeomFieldDefn *myGetGeomFieldDefn(int i)
85 : {
86 27875 : return cpl::down_cast<OGRSQLiteGeomFieldDefn *>(GetGeomFieldDefn(i));
87 : }
88 :
89 6 : const OGRSQLiteGeomFieldDefn *myGetGeomFieldDefn(int i) const
90 : {
91 6 : return cpl::down_cast<const OGRSQLiteGeomFieldDefn *>(
92 12 : GetGeomFieldDefn(i));
93 : }
94 : };
95 :
96 : /************************************************************************/
97 : /* IOGRSQLiteGetSpatialWhere */
98 : /************************************************************************/
99 :
100 8104 : class IOGRSQLiteGetSpatialWhere /* non final */
101 : {
102 : public:
103 : virtual ~IOGRSQLiteGetSpatialWhere();
104 :
105 : virtual bool HasFastSpatialFilter(int iGeomCol) = 0;
106 : virtual CPLString GetSpatialWhere(int iGeomCol,
107 : OGRGeometry *poFilterGeom) = 0;
108 : };
109 :
110 : /************************************************************************/
111 : /* OGRSQLiteBaseDataSource */
112 : /************************************************************************/
113 :
114 : /* Used by both OGRSQLiteDataSource and OGRGeoPackageDataSource */
115 3839 : class OGRSQLiteBaseDataSource CPL_NON_FINAL : public GDALPamDataset
116 : {
117 : protected:
118 : char *m_pszFilename = nullptr;
119 : std::string
120 : m_osFilenameForSQLiteOpen{}; // generally m_pszFilename, but can be
121 : // also file:{m_pszFilename}?nolock=1
122 : bool m_bNoLock = false;
123 : std::string
124 : m_osFinalFilename{}; // use when generating a network hosted file with
125 : // CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE=YES
126 : bool m_bCallUndeclareFileNotToOpen = false;
127 :
128 : sqlite3 *hDB = nullptr;
129 :
130 : sqlite3_vfs *pMyVFS = nullptr;
131 :
132 : VSILFILE *fpMainFile =
133 : nullptr; /* Set by the VFS layer when it opens the DB */
134 : /* Must *NOT* be closed by the datasource explicitly. */
135 :
136 : bool OpenOrCreateDB(int flags, bool bRegisterOGR2SQLiteExtensions,
137 : bool bLoadExtensions);
138 : bool SetSynchronous();
139 : bool SetCacheSize();
140 : void LoadExtensions();
141 :
142 : bool CloseDB();
143 :
144 : std::map<CPLString, OGREnvelope> oMapSQLEnvelope{};
145 :
146 : mutable bool m_bHasPopulatedRelationships = false;
147 : mutable std::map<std::string, std::unique_ptr<GDALRelationship>>
148 : m_osMapRelationships{};
149 :
150 : void *hSpatialiteCtxt = nullptr;
151 : bool InitSpatialite();
152 : void FinishSpatialite();
153 :
154 : int m_bUserTransactionActive = FALSE;
155 : int m_nSoftTransactionLevel = 0;
156 : std::vector<std::string> m_aosSavepoints{};
157 : // The transaction was implicitly started by SAVEPOINT
158 : bool m_bImplicitTransactionOpened = false;
159 :
160 : OGRErr DoTransactionCommand(const char *pszCommand);
161 :
162 : bool DealWithOgrSchemaOpenOption(CSLConstList papszOpenOptionsIn);
163 :
164 : CPL_DISALLOW_COPY_ASSIGN(OGRSQLiteBaseDataSource)
165 :
166 : public:
167 : OGRSQLiteBaseDataSource();
168 : ~OGRSQLiteBaseDataSource() override;
169 :
170 1639 : std::string GetCurrentSavepoint() const
171 : {
172 1639 : return m_aosSavepoints.empty() ? "" : m_aosSavepoints.back();
173 : }
174 :
175 : std::string GetFirstSavepoint() const
176 : {
177 : return m_aosSavepoints.empty() ? "" : m_aosSavepoints.front();
178 : }
179 :
180 : bool IsInTransaction() const;
181 :
182 342836 : sqlite3 *GetDB()
183 : {
184 342836 : return hDB;
185 : }
186 :
187 72 : sqlite3_vfs *GetVFS()
188 : {
189 72 : return pMyVFS;
190 : }
191 :
192 318592 : inline bool GetUpdate() const
193 : {
194 318592 : return eAccess == GA_Update;
195 : }
196 :
197 3 : VSILFILE *GetVSILFILE() const
198 : {
199 3 : return fpMainFile;
200 : }
201 :
202 : void NotifyFileOpened(const char *pszFilename, VSILFILE *fp);
203 :
204 : const OGREnvelope *GetEnvelopeFromSQL(const CPLString &osSQL);
205 : void SetEnvelopeForSQL(const CPLString &osSQL,
206 : const OGREnvelope &oEnvelope);
207 :
208 : virtual std::pair<OGRLayer *, IOGRSQLiteGetSpatialWhere *>
209 : GetLayerWithGetSpatialWhereByName(const char *pszName) = 0;
210 :
211 : OGRErr AbortSQL() override;
212 : bool SetQueryLoggerFunc(GDALQueryLoggerFunc pfnQueryLoggerFuncIn,
213 : void *poQueryLoggerArgIn) override;
214 :
215 : OGRErr StartTransaction(int bForce = FALSE) override;
216 : OGRErr CommitTransaction() override;
217 : OGRErr RollbackTransaction() override;
218 :
219 : int TestCapability(const char *) const override;
220 :
221 : void *GetInternalHandle(const char *) override;
222 :
223 : OGRErr SoftStartTransaction();
224 : OGRErr SoftCommitTransaction();
225 : OGRErr SoftRollbackTransaction();
226 : OGRErr StartSavepoint(const std::string &osName);
227 : OGRErr ReleaseSavepoint(const std::string &osName);
228 : OGRErr RollbackToSavepoint(const std::string &osName);
229 :
230 : /**
231 : * Execute a SQL transaction command (BEGIN, COMMIT, ROLLBACK, SAVEPOINT)
232 : * @return TRUE if the osSQLCommand was recognized as a transaction command
233 : */
234 : bool ProcessTransactionSQL(const std::string &osSQLCommand);
235 :
236 : OGRErr PragmaCheck(const char *pszPragma, const char *pszExpected,
237 : int nRowsExpected);
238 :
239 : virtual void LoadRelationships() const;
240 : void LoadRelationshipsFromForeignKeys(
241 : const std::vector<std::string> &excludedTables) const;
242 : std::vector<std::string>
243 : GetRelationshipNames(CSLConstList papszOptions = nullptr) const override;
244 : const GDALRelationship *
245 : GetRelationship(const std::string &name) const override;
246 :
247 : bool IsSpatialiteLoaded();
248 :
249 10695 : static int MakeSpatialiteVersionNumber(int x, int y, int z)
250 : {
251 10695 : return x * 10000 + y * 100 + z;
252 : }
253 :
254 : int GetSpatialiteVersionNumber();
255 :
256 : bool SpatialiteRequiresTrustedSchemaOn();
257 : bool AreSpatialiteTriggersSafe();
258 :
259 : // sqlite3_prepare_v2 error logging wrapper
260 : int
261 : prepareSql(sqlite3 *db, /* Database handle */
262 : const char *zSql, /* SQL statement, UTF-8 encoded */
263 : int nByte, /* Maximum length of zSql in bytes. */
264 : sqlite3_stmt **ppStmt, /* OUT: Statement handle */
265 : const char **pzTail /* OUT: Pointer to unused portion of zSql */
266 : );
267 :
268 : GDALQueryLoggerFunc pfnQueryLoggerFunc = nullptr;
269 : void *poQueryLoggerArg = nullptr;
270 : };
271 :
272 : /************************************************************************/
273 : /* IOGRSQLiteSelectLayer */
274 : /************************************************************************/
275 :
276 2222 : class IOGRSQLiteSelectLayer /* non final */
277 : {
278 : public:
279 : virtual ~IOGRSQLiteSelectLayer();
280 :
281 : virtual char *&GetAttrQueryString() = 0;
282 : virtual OGRFeatureQuery *&GetFeatureQuery() = 0;
283 : virtual OGRGeometry *&GetFilterGeom() = 0;
284 : virtual int &GetIGeomFieldFilter() = 0;
285 : virtual const OGRSpatialReference *GetSpatialRef() const = 0;
286 : virtual const OGRFeatureDefn *GetLayerDefn() const = 0;
287 : virtual int InstallFilter(const OGRGeometry *) = 0;
288 : virtual int HasReadFeature() = 0;
289 : virtual void BaseResetReading() = 0;
290 : virtual OGRFeature *BaseGetNextFeature() = 0;
291 : virtual OGRErr BaseSetAttributeFilter(const char *pszQuery) = 0;
292 : virtual GIntBig BaseGetFeatureCount(int bForce) = 0;
293 : virtual int BaseTestCapability(const char *) const = 0;
294 : virtual OGRErr BaseGetExtent(int iGeomField, OGREnvelope *psExtent,
295 : bool bForce) = 0;
296 : virtual bool ValidateGeometryFieldIndexForSetSpatialFilter(
297 : int iGeomField, const OGRGeometry *poGeomIn, bool bIsSelectLayer) = 0;
298 : };
299 :
300 : /************************************************************************/
301 : /* OGRSQLiteSelectLayerCommonBehaviour */
302 : /************************************************************************/
303 :
304 : class OGRSQLiteSelectLayerCommonBehaviour final
305 : {
306 : OGRSQLiteBaseDataSource *m_poDS = nullptr;
307 : IOGRSQLiteSelectLayer *m_poLayer = nullptr;
308 :
309 : CPLString m_osSQLBase{};
310 :
311 : bool m_bEmptyLayer = false;
312 : bool m_bAllowResetReadingEvenIfIndexAtZero = false;
313 : bool m_bSpatialFilterInSQL = true;
314 :
315 : std::pair<OGRLayer *, IOGRSQLiteGetSpatialWhere *>
316 : GetBaseLayer(size_t &i) const;
317 : int BuildSQL();
318 :
319 : CPL_DISALLOW_COPY_ASSIGN(OGRSQLiteSelectLayerCommonBehaviour)
320 :
321 : public:
322 : CPLString m_osSQLCurrent{};
323 :
324 : OGRSQLiteSelectLayerCommonBehaviour(OGRSQLiteBaseDataSource *poDS,
325 : IOGRSQLiteSelectLayer *poBaseLayer,
326 : const CPLString &osSQL,
327 : bool bEmptyLayer);
328 :
329 : void ResetReading();
330 : OGRFeature *GetNextFeature();
331 : GIntBig GetFeatureCount(int);
332 : OGRErr SetSpatialFilter(int iGeomField, const OGRGeometry *);
333 : OGRErr SetAttributeFilter(const char *);
334 : int TestCapability(const char *) const;
335 : OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent, bool bForce);
336 : };
337 :
338 : /************************************************************************/
339 : /* OGRSQLiteSingleFeatureLayer */
340 : /************************************************************************/
341 :
342 : class OGRSQLiteSingleFeatureLayer final : public OGRLayer
343 : {
344 : private:
345 : int nVal;
346 : char *pszVal;
347 : OGRFeatureDefn *poFeatureDefn;
348 : int iNextShapeId;
349 :
350 : CPL_DISALLOW_COPY_ASSIGN(OGRSQLiteSingleFeatureLayer)
351 :
352 : public:
353 : OGRSQLiteSingleFeatureLayer(const char *pszLayerName, int nVal);
354 : OGRSQLiteSingleFeatureLayer(const char *pszLayerName, const char *pszVal);
355 : ~OGRSQLiteSingleFeatureLayer() override;
356 :
357 : void ResetReading() override;
358 : OGRFeature *GetNextFeature() override;
359 : const OGRFeatureDefn *GetLayerDefn() const override;
360 : int TestCapability(const char *) const override;
361 : };
362 :
363 : /************************************************************************/
364 : /* Functions */
365 : /************************************************************************/
366 :
367 : OGRErr OGRSQLiteGetSpatialiteGeometryHeader(const GByte *pabyData, int nBytes,
368 : int *pnSRID,
369 : OGRwkbGeometryType *peType,
370 : bool *pbIsEmpty, double *pdfMinX,
371 : double *pdfMinY, double *pdfMaxX,
372 : double *pdfMaxY);
373 : // CPL_DLL just for spatialite_geom_import_fuzzer
374 : OGRErr CPL_DLL OGRSQLiteImportSpatiaLiteGeometry(const GByte *, int,
375 : OGRGeometry **,
376 : int *pnSRID = nullptr);
377 : OGRErr OGRSQLiteExportSpatiaLiteGeometry(const OGRGeometry *, GInt32,
378 : OGRwkbByteOrder, bool bSpatialite2D,
379 : bool bUseComprGeom, GByte **, int *);
380 : #endif // OGR_SQLITE_BASE_H_INCLUDED
|