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_WKT,
38 : OSGF_WKB,
39 : OSGF_FGF,
40 : OSGF_SpatiaLite,
41 : OSGF_Unknown,
42 : };
43 :
44 : /************************************************************************/
45 : /* OGRSQLiteGeomFieldDefn */
46 : /************************************************************************/
47 :
48 1896 : class OGRSQLiteGeomFieldDefn final : public OGRGeomFieldDefn
49 : {
50 : public:
51 949 : OGRSQLiteGeomFieldDefn(const char *pszNameIn, int iGeomColIn)
52 949 : : OGRGeomFieldDefn(pszNameIn, wkbUnknown), m_iCol(iGeomColIn)
53 : {
54 949 : }
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_Unknown;
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 7556 : class OGRSQLiteFeatureDefn final : public OGRFeatureDefn
74 : {
75 : public:
76 3779 : explicit OGRSQLiteFeatureDefn(const char *pszName = nullptr)
77 3779 : : OGRFeatureDefn(pszName)
78 : {
79 3779 : SetGeomType(wkbNone);
80 3779 : }
81 :
82 : ~OGRSQLiteFeatureDefn() override;
83 :
84 28013 : OGRSQLiteGeomFieldDefn *myGetGeomFieldDefn(int i)
85 : {
86 28013 : 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 8400 : 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 4025 : 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 1672 : std::string GetCurrentSavepoint() const
171 : {
172 1672 : 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 345947 : sqlite3 *GetDB()
183 : {
184 345947 : return hDB;
185 : }
186 :
187 72 : sqlite3_vfs *GetVFS()
188 : {
189 72 : return pMyVFS;
190 : }
191 :
192 321519 : inline bool GetUpdate() const
193 : {
194 321519 : 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 10993 : static int MakeSpatialiteVersionNumber(int x, int y, int z)
250 : {
251 10993 : 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 : sqlite3_stmt *
261 : prepareSql(sqlite3 *db, /* Database handle */
262 : const char *zSql, /* SQL statement, UTF-8 encoded */
263 : int nByte = -1 /* Maximum length of zSql in bytes. */
264 : );
265 :
266 : GDALQueryLoggerFunc pfnQueryLoggerFunc = nullptr;
267 : void *poQueryLoggerArg = nullptr;
268 : };
269 :
270 : /************************************************************************/
271 : /* IOGRSQLiteSelectLayer */
272 : /************************************************************************/
273 :
274 2334 : class IOGRSQLiteSelectLayer /* non final */
275 : {
276 : public:
277 : virtual ~IOGRSQLiteSelectLayer();
278 :
279 : virtual char *&GetAttrQueryString() = 0;
280 : virtual OGRFeatureQuery *&GetFeatureQuery() = 0;
281 : virtual OGRGeometry *&GetFilterGeom() = 0;
282 : virtual int &GetIGeomFieldFilter() = 0;
283 : virtual const OGRSpatialReference *GetSpatialRef() const = 0;
284 : virtual const OGRFeatureDefn *GetLayerDefn() const = 0;
285 : virtual int InstallFilter(const OGRGeometry *) = 0;
286 : virtual int HasReadFeature() = 0;
287 : virtual void BaseResetReading() = 0;
288 : virtual OGRFeature *BaseGetNextFeature() = 0;
289 : virtual OGRErr BaseSetAttributeFilter(const char *pszQuery) = 0;
290 : virtual GIntBig BaseGetFeatureCount(int bForce) = 0;
291 : virtual int BaseTestCapability(const char *) const = 0;
292 : virtual OGRErr BaseGetExtent(int iGeomField, OGREnvelope *psExtent,
293 : bool bForce) = 0;
294 : virtual bool ValidateGeometryFieldIndexForSetSpatialFilter(
295 : int iGeomField, const OGRGeometry *poGeomIn, bool bIsSelectLayer) = 0;
296 : };
297 :
298 : /************************************************************************/
299 : /* OGRSQLiteSelectLayerCommonBehaviour */
300 : /************************************************************************/
301 :
302 : class OGRSQLiteSelectLayerCommonBehaviour final
303 : {
304 : OGRSQLiteBaseDataSource *m_poDS = nullptr;
305 : IOGRSQLiteSelectLayer *m_poLayer = nullptr;
306 :
307 : CPLString m_osSQLBase{};
308 :
309 : bool m_bEmptyLayer = false;
310 : bool m_bAllowResetReadingEvenIfIndexAtZero = false;
311 : bool m_bSpatialFilterInSQL = true;
312 :
313 : std::pair<OGRLayer *, IOGRSQLiteGetSpatialWhere *>
314 : GetBaseLayer(size_t &i) const;
315 : int BuildSQL();
316 :
317 : CPL_DISALLOW_COPY_ASSIGN(OGRSQLiteSelectLayerCommonBehaviour)
318 :
319 : public:
320 : CPLString m_osSQLCurrent{};
321 :
322 : OGRSQLiteSelectLayerCommonBehaviour(OGRSQLiteBaseDataSource *poDS,
323 : IOGRSQLiteSelectLayer *poBaseLayer,
324 : const CPLString &osSQL,
325 : bool bEmptyLayer);
326 :
327 : void ResetReading();
328 : OGRFeature *GetNextFeature();
329 : GIntBig GetFeatureCount(int);
330 : OGRErr SetSpatialFilter(int iGeomField, const OGRGeometry *);
331 : OGRErr SetAttributeFilter(const char *);
332 : int TestCapability(const char *) const;
333 : OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent, bool bForce);
334 : };
335 :
336 : /************************************************************************/
337 : /* OGRSQLiteSingleFeatureLayer */
338 : /************************************************************************/
339 :
340 : class OGRSQLiteSingleFeatureLayer final : public OGRLayer
341 : {
342 : private:
343 : int nVal;
344 : char *pszVal;
345 : OGRFeatureDefn *poFeatureDefn;
346 : int iNextShapeId;
347 :
348 : CPL_DISALLOW_COPY_ASSIGN(OGRSQLiteSingleFeatureLayer)
349 :
350 : public:
351 : OGRSQLiteSingleFeatureLayer(const char *pszLayerName, int nVal);
352 : OGRSQLiteSingleFeatureLayer(const char *pszLayerName, const char *pszVal);
353 : ~OGRSQLiteSingleFeatureLayer() override;
354 :
355 : void ResetReading() override;
356 : OGRFeature *GetNextFeature() override;
357 : const OGRFeatureDefn *GetLayerDefn() const override;
358 : int TestCapability(const char *) const override;
359 : };
360 :
361 : /************************************************************************/
362 : /* Functions */
363 : /************************************************************************/
364 :
365 : OGRErr OGRSQLiteGetSpatialiteGeometryHeader(const GByte *pabyData, int nBytes,
366 : int *pnSRID,
367 : OGRwkbGeometryType *peType,
368 : bool *pbIsEmpty, double *pdfMinX,
369 : double *pdfMinY, double *pdfMaxX,
370 : double *pdfMaxY);
371 : // CPL_DLL just for spatialite_geom_import_fuzzer
372 : OGRErr CPL_DLL OGRSQLiteImportSpatiaLiteGeometry(const GByte *, int,
373 : OGRGeometry **,
374 : int *pnSRID = nullptr);
375 : OGRErr OGRSQLiteExportSpatiaLiteGeometry(const OGRGeometry *, GInt32,
376 : OGRwkbByteOrder, bool bSpatialite2D,
377 : bool bUseComprGeom, GByte **, int *);
378 : #endif // OGR_SQLITE_BASE_H_INCLUDED
|