1 /******************************************************************************
2  * $Id: ogr_geopackage.h 09a48d5214b089c224b3b7afed5beee254d45614 2021-08-15 12:04:53 +0200 Even Rouault $
3  *
4  * Project:  GeoPackage Translator
5  * Purpose:  Definition of classes for OGR GeoPackage driver.
6  * Author:   Paul Ramsey, pramsey@boundlessgeo.com
7  *
8  ******************************************************************************
9  * Copyright (c) 2013, Paul Ramsey <pramsey@boundlessgeo.com>
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 #ifndef OGR_GEOPACKAGE_H_INCLUDED
31 #define OGR_GEOPACKAGE_H_INCLUDED
32 
33 #include "ogrsf_frmts.h"
34 #include "ogrsqlitebase.h"
35 #include "gpkgmbtilescommon.h"
36 #include "ogrsqliteutility.h"
37 
38 #include <vector>
39 #include <set>
40 
41 #define UNKNOWN_SRID   -2
42 #define DEFAULT_SRID    0
43 
44 #define ENABLE_GPKG_OGR_CONTENTS
45 
46 #if defined(DEBUG) || defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) || defined(ALLOW_FORMAT_DUMPS)
47 // Enable accepting a SQL dump (starting with a "-- SQL GPKG" line) as a valid
48 // file. This makes fuzzer life easier
49 #define ENABLE_SQL_GPKG_FORMAT
50 #endif
51 
52 typedef enum
53 {
54     GPKG_ATTRIBUTES,
55     NOT_REGISTERED,
56 } GPKGASpatialVariant;
57 
58 // Requirement 2
59 static const GUInt32 GP10_APPLICATION_ID = 0x47503130U;
60 static const GUInt32 GP11_APPLICATION_ID = 0x47503131U;
61 static const GUInt32 GPKG_APPLICATION_ID = 0x47504B47U;
62 static const GUInt32 GPKG_1_2_VERSION = 10200U;
63 static const GUInt32 GPKG_1_3_VERSION = 10300U;
64 
65 static const size_t knApplicationIdPos = 68;
66 static const size_t knUserVersionPos = 60;
67 
68 typedef struct
69 {
70     CPLString osExtensionName;
71     CPLString osDefinition;
72     CPLString osScope;
73 } GPKGExtensionDesc;
74 
75 typedef struct
76 {
77     CPLString osDataType;
78     CPLString osIdentifier;
79     CPLString osDescription;
80     CPLString osMinX;
81     CPLString osMinY;
82     CPLString osMaxX;
83     CPLString osMaxY;
84 } GPKGContentsDesc;
85 
86 /************************************************************************/
87 /*                          GDALGeoPackageDataset                       */
88 /************************************************************************/
89 
90 class OGRGeoPackageTableLayer;
91 
92 class GDALGeoPackageDataset final : public OGRSQLiteBaseDataSource, public GDALGPKGMBTilesLikePseudoDataset
93 {
94     friend class GDALGeoPackageRasterBand;
95     friend class OGRGeoPackageLayer;
96     friend class OGRGeoPackageTableLayer;
97 
98     GUInt32             m_nApplicationId;
99     GUInt32             m_nUserVersion;
100     OGRGeoPackageTableLayer** m_papoLayers;
101     int                 m_nLayers;
102     void                CheckUnknownExtensions(bool bCheckRasterTable = false);
103 #ifdef ENABLE_GPKG_OGR_CONTENTS
104     bool                m_bHasGPKGOGRContents;
105 #endif
106     bool                m_bHasGPKGGeometryColumns;
107     bool                m_bHasDefinition12_063;
108 
109     CPLString           m_osIdentifier;
110     bool                m_bIdentifierAsCO;
111     CPLString           m_osDescription;
112     bool                m_bDescriptionAsCO;
113     bool                m_bGridCellEncodingAsCO = false;
114     bool                m_bHasReadMetadataFromStorage;
115     bool                m_bMetadataDirty;
116     CPLStringList       m_aosSubDatasets{};
117     char               *m_pszProjection;
118     bool                m_bRecordInsertedInGPKGContent;
119     bool                m_bGeoTransformValid;
120     double              m_adfGeoTransform[6];
121     int                 m_nSRID;
122     double              m_dfTMSMinX;
123     double              m_dfTMSMaxY;
124 
125     int                 m_nOverviewCount;
126     GDALGeoPackageDataset** m_papoOverviewDS;
127     bool                m_bZoomOther;
128 
129     bool                m_bInFlushCache;
130 
131     bool                m_bDateTimeWithTZ = true;
132 
133     CPLString           m_osTilingScheme;
134 
135         bool            ComputeTileAndPixelShifts();
136         bool            AllocCachedTiles();
137         bool            InitRaster ( GDALGeoPackageDataset* poParentDS,
138                                      const char* pszTableName,
139                                      double dfMinX,
140                                      double dfMinY,
141                                      double dfMaxX,
142                                      double dfMaxY,
143                                      const char* pszContentsMinX,
144                                      const char* pszContentsMinY,
145                                      const char* pszContentsMaxX,
146                                      const char* pszContentsMaxY,
147                                      char** papszOpenOptions,
148                                      const SQLResult& oResult,
149                                      int nIdxInResult );
150         bool            InitRaster ( GDALGeoPackageDataset* poParentDS,
151                                      const char* pszTableName,
152                                      int nZoomLevel,
153                                      int nBandCount,
154                                      double dfTMSMinX,
155                                      double dfTMSMaxY,
156                                      double dfPixelXSize,
157                                      double dfPixelYSize,
158                                      int nTileWidth,
159                                      int nTileHeight,
160                                      int nTileMatrixWidth,
161                                      int nTileMatrixHeight,
162                                      double dfGDALMinX,
163                                      double dfGDALMinY,
164                                      double dfGDALMaxX,
165                                      double dfGDALMaxY );
166 
167         bool    OpenRaster( const char* pszTableName,
168                             const char* pszIdentifier,
169                             const char* pszDescription,
170                             int nSRSId,
171                             double dfMinX,
172                             double dfMinY,
173                             double dfMaxX,
174                             double dfMaxY,
175                             const char* pszContentsMinX,
176                             const char* pszContentsMinY,
177                             const char* pszContentsMaxX,
178                             const char* pszContentsMaxY,
179                             bool bIsTiles,
180                             char** papszOptions );
181         CPLErr   FinalizeRasterRegistration();
182 
183         bool                    RegisterWebPExtension();
184         bool                    RegisterZoomOtherExtension();
185         void                    ParseCompressionOptions(char** papszOptions);
186 
187         bool                    HasMetadataTables() const;
188         bool                    CreateMetadataTables();
189         const char*             CheckMetadataDomain( const char* pszDomain );
190         void                    WriteMetadata(CPLXMLNode* psXMLNode, /* will be destroyed by the method */
191                                               const char* pszTableName);
192         CPLErr                  FlushMetadata();
193 
194         int                     FindLayerIndex(const char* pszLayerName);
195 
196         bool                    HasGriddedCoverageAncillaryTable();
197         bool                    CreateTileGriddedTable(char** papszOptions);
198 
199         void                    RemoveOGREmptyTable();
200 
201         std::map<CPLString, CPLString> m_oMapNameToType;
202         const std::map<CPLString, CPLString>&
203                                         GetNameTypeMapFromSQliteMaster();
204         void RemoveTableFromSQLiteMasterCache(const char* pszTableName);
205 
206         bool                    m_bMapTableToExtensionsBuilt;
207         std::map< CPLString, std::vector<GPKGExtensionDesc> > m_oMapTableToExtensions;
208         const std::map< CPLString, std::vector<GPKGExtensionDesc> > &
209                                         GetUnknownExtensionsTableSpecific();
210 
211         bool                    m_bMapTableToContentsBuilt;
212         std::map< CPLString, GPKGContentsDesc > m_oMapTableToContents;
213         const std::map< CPLString, GPKGContentsDesc > & GetContents();
214 
215         std::map<int, OGRSpatialReference*> m_oMapSrsIdToSrs;
216 
217         OGRErr              DeleteLayerCommon( const char* pszLayerName );
218         OGRErr              DeleteRasterLayer( const char* pszLayerName );
219         bool                DeleteVectorOrRasterLayer(
220                                                 const char* pszLayerName );
221 
222         bool                ConvertGpkgSpatialRefSysToExtensionWkt2();
223 
224         std::map<int, bool> m_oSetGPKGLayerWarnings{};
225 
226         void                FixupWrongRTreeTrigger();
227         void                FixupWrongMedataReferenceColumnNameUpdate();
228 
229     public:
230                             GDALGeoPackageDataset();
231                             virtual ~GDALGeoPackageDataset();
232 
233         virtual char **     GetMetadata( const char *pszDomain = nullptr ) override;
234         virtual const char *GetMetadataItem( const char * pszName,
235                                              const char * pszDomain = "" ) override;
236         virtual char **     GetMetadataDomainList() override;
237         virtual CPLErr      SetMetadata( char ** papszMetadata,
238                                          const char * pszDomain = "" ) override;
239         virtual CPLErr      SetMetadataItem( const char * pszName,
240                                              const char * pszValue,
241                                              const char * pszDomain = "" ) override;
242 
243         virtual const char* _GetProjectionRef() override;
244         virtual CPLErr      _SetProjection( const char* pszProjection ) override;
GetSpatialRef()245         const OGRSpatialReference* GetSpatialRef() const override {
246             return GetSpatialRefFromOldGetProjectionRef();
247         }
SetSpatialRef(const OGRSpatialReference * poSRS)248         CPLErr SetSpatialRef(const OGRSpatialReference* poSRS) override {
249             return OldSetProjectionFromSetSpatialRef(poSRS);
250         }
251 
252         virtual CPLErr      GetGeoTransform( double* padfGeoTransform ) override;
253         virtual CPLErr      SetGeoTransform( double* padfGeoTransform ) override;
254 
255         virtual void        FlushCache() override;
256         virtual CPLErr      IBuildOverviews( const char *, int, int *,
257                                              int, int *, GDALProgressFunc, void * ) override;
258 
GetLayerCount()259         virtual int         GetLayerCount() override { return m_nLayers; }
260         int                 Open( GDALOpenInfo* poOpenInfo );
261         int                 Create( const char * pszFilename,
262                                     int nXSize,
263                                     int nYSize,
264                                     int nBands,
265                                     GDALDataType eDT,
266                                     char **papszOptions );
267         OGRLayer*           GetLayer( int iLayer ) override;
268         OGRErr              DeleteLayer( int iLayer ) override;
269         OGRLayer*           ICreateLayer( const char * pszLayerName,
270                                          OGRSpatialReference * poSpatialRef,
271                                          OGRwkbGeometryType eGType,
272                                          char **papszOptions ) override;
273         int                 TestCapability( const char * ) override;
274 
275         const OGRFieldDomain* GetFieldDomain(const std::string& name) const override;
276         bool                AddFieldDomain(std::unique_ptr<OGRFieldDomain>&& domain,
277                                            std::string& failureReason) override;
278 
279         virtual std::pair<OGRLayer*, IOGRSQLiteGetSpatialWhere*> GetLayerWithGetSpatialWhereByName( const char* pszName ) override;
280 
281         virtual OGRLayer *  ExecuteSQL( const char *pszSQLCommand,
282                                         OGRGeometry *poSpatialFilter,
283                                         const char *pszDialect ) override;
284         virtual void        ReleaseResultSet( OGRLayer * poLayer ) override;
285 
286         virtual OGRErr      CommitTransaction() override;
287         virtual OGRErr      RollbackTransaction() override;
288 
IsInTransaction()289         inline bool         IsInTransaction() const { return nSoftTransactionLevel > 0; }
290 
291         int                 GetSrsId( const OGRSpatialReference& oSRS );
292         const char*         GetSrsName( const OGRSpatialReference& oSRS );
293         OGRSpatialReference* GetSpatialRef( int iSrsId, bool bFallbackToEPSG = false );
294         OGRErr              CreateExtensionsTableIfNecessary();
295         bool                HasExtensionsTable();
SetMetadataDirty()296         void                SetMetadataDirty() { m_bMetadataDirty = true; }
297 
298         bool                    HasDataColumnsTable() const;
299         bool                    HasDataColumnConstraintsTable() const;
300         bool                CreateColumnsTableAndColumnConstraintsTablesIfNecessary();
301 
302         const char*         GetGeometryTypeString(OGRwkbGeometryType eType);
303 
304         void                ResetReadingAllLayers();
305         OGRErr              UpdateGpkgContentsLastChange(
306                                                 const char* pszTableName);
307 
308         static GDALDataset* CreateCopy( const char *pszFilename,
309                                                    GDALDataset *poSrcDS,
310                                                    int bStrict,
311                                                    char ** papszOptions,
312                                                    GDALProgressFunc pfnProgress,
313                                                    void * pProgressData );
314 
315         static std::string GetCurrentDateEscapedSQL();
316 
317     protected:
318         // Coming from GDALGPKGMBTilesLikePseudoDataset
319 
320         virtual CPLErr                  IFlushCacheWithErrCode() override;
IGetRasterCount()321         virtual int                     IGetRasterCount() override { return nBands; }
IGetRasterBand(int nBand)322         virtual GDALRasterBand*         IGetRasterBand(int nBand) override { return GetRasterBand(nBand); }
IGetDB()323         virtual sqlite3                *IGetDB() override { return GetDB(); }
IGetUpdate()324         virtual bool                    IGetUpdate() override { return GetUpdate(); }
325         virtual bool                    ICanIWriteBlock() override;
IStartTransaction()326         virtual OGRErr                  IStartTransaction() override { return SoftStartTransaction(); }
ICommitTransaction()327         virtual OGRErr                  ICommitTransaction() override { return SoftCommitTransaction(); }
IGetFilename()328         virtual const char             *IGetFilename() override { return m_pszFilename; }
GetRowFromIntoTopConvention(int nRow)329         virtual int                     GetRowFromIntoTopConvention(int nRow) override { return nRow; }
330 
331     private:
332 
333         OGRErr              PragmaCheck(const char * pszPragma, const char * pszExpected, int nRowsExpected);
334         OGRErr              SetApplicationAndUserVersionId();
335         bool                ReOpenDB();
336         bool                OpenOrCreateDB( int flags );
337         void                InstallSQLFunctions();
338         bool                HasGDALAspatialExtension();
339 };
340 
341 /************************************************************************/
342 /*                        GDALGeoPackageRasterBand                      */
343 /************************************************************************/
344 
345 class GDALGeoPackageRasterBand final: public GDALGPKGMBTilesLikeRasterBand
346 {
347         bool                    m_bStatsComputed;
348 
349     public:
350                                 GDALGeoPackageRasterBand(GDALGeoPackageDataset* poDS,
351                                                          int nTileWidth, int nTileHeight);
352 
353         virtual int             GetOverviewCount() override;
354         virtual GDALRasterBand* GetOverview(int nIdx) override;
355 
356         virtual CPLErr          SetNoDataValue( double dfNoDataValue ) override;
357 
358         virtual char**          GetMetadata(const char* pszDomain = "") override;
359         virtual const char*     GetMetadataItem(const char* pszName,
360                                                 const char* pszDomain = "") override;
361 };
362 
363 /************************************************************************/
364 /*                           OGRGeoPackageLayer                         */
365 /************************************************************************/
366 
367 class OGRGeoPackageLayer CPL_NON_FINAL: public OGRLayer, public IOGRSQLiteGetSpatialWhere
368 {
369   protected:
370     GDALGeoPackageDataset *m_poDS;
371 
372     OGRFeatureDefn*      m_poFeatureDefn;
373     int                  iNextShapeId;
374 
375     sqlite3_stmt        *m_poQueryStatement;
376     bool                 bDoStep;
377     bool                 m_bEOF = false;
378 
379     char                *m_pszFidColumn;
380 
381     int                 iFIDCol;
382     int                 iGeomCol;
383     int                *panFieldOrdinals;
384 
385     void                ClearStatement();
386     virtual OGRErr      ResetStatement() = 0;
387 
388     void                BuildFeatureDefn( const char *pszLayerName,
389                                            sqlite3_stmt *hStmt );
390 
391     OGRFeature*         TranslateFeature(sqlite3_stmt* hStmt);
392 
393   public:
394 
395     explicit            OGRGeoPackageLayer(GDALGeoPackageDataset* poDS);
396                         virtual ~OGRGeoPackageLayer();
397     /************************************************************************/
398     /* OGR API methods */
399 
400     OGRFeature*         GetNextFeature() override;
401     const char*         GetFIDColumn() override;
402     void                ResetReading() override;
403     int                 TestCapability( const char * ) override;
GetLayerDefn()404     OGRFeatureDefn*     GetLayerDefn() override { return m_poFeatureDefn; }
405 
HasFastSpatialFilter(int)406     virtual int          HasFastSpatialFilter(int /*iGeomCol*/) override { return FALSE; }
GetSpatialWhere(int,OGRGeometry *)407     virtual CPLString    GetSpatialWhere(int /*iGeomCol*/,
408                                          OGRGeometry* /*poFilterGeom*/) override { return ""; }
409 };
410 
411 /************************************************************************/
412 /*                        OGRGeoPackageTableLayer                       */
413 /************************************************************************/
414 
415 class OGRGeoPackageTableLayer final : public OGRGeoPackageLayer
416 {
417     char*                       m_pszTableName;
418     bool                        m_bIsTable;
419     bool                        m_bIsSpatial;
420     bool                        m_bIsInGpkgContents;
421     bool                        m_bFeatureDefnCompleted;
422     int                         m_iSrs;
423     int                         m_nZFlag = 0;
424     int                         m_nMFlag = 0;
425     OGREnvelope*                m_poExtent;
426 #ifdef ENABLE_GPKG_OGR_CONTENTS
427     GIntBig                     m_nTotalFeatureCount;
428     bool                        m_bOGRFeatureCountTriggersEnabled;
429     bool                        m_bAddOGRFeatureCountTriggers;
430     bool                        m_bFeatureCountTriggersDeletedInTransaction;
431 #endif
432     CPLString                   m_soColumns;
433     CPLString                   m_soFilter;
434     CPLString                   osQuery;
435     CPLString                   m_osRTreeName;
436     CPLString                   m_osFIDForRTree;
437     bool                        m_bExtentChanged;
438     bool                        m_bContentChanged;
439     sqlite3_stmt*               m_poUpdateStatement;
440     bool                        m_bInsertStatementWithFID;
441     sqlite3_stmt*               m_poInsertStatement;
442     bool                        m_bDeferredSpatialIndexCreation;
443     // m_bHasSpatialIndex cannot be bool.  -1 is unset.
444     int                         m_bHasSpatialIndex;
445     bool                        m_bDropRTreeTable;
446     bool                        m_abHasGeometryExtension[wkbTriangle+1];
447     bool                        m_bPreservePrecision;
448     bool                        m_bTruncateFields;
449     bool                        m_bDeferredCreation;
450     int                         m_iFIDAsRegularColumnIndex;
451 
452     CPLString                   m_osIdentifierLCO;
453     CPLString                   m_osDescriptionLCO;
454     bool                        m_bHasReadMetadataFromStorage;
455     bool                        m_bHasTriedDetectingFID64;
456     GPKGASpatialVariant         m_eASpatialVariant;
457     std::set<OGRwkbGeometryType> m_eSetBadGeomTypeWarned;
458 
459     int                         m_nCountInsertInTransactionThreshold = -1;
460     GIntBig                     m_nCountInsertInTransaction = 0;
461     std::vector<CPLString >     m_aoRTreeTriggersSQL{};
462     typedef struct
463     {
464         GIntBig nId;
465         float   fMinX;
466         float   fMinY;
467         float   fMaxX;
468         float   fMaxY;
469     } GPKGRTreeEntry;
470     std::vector<GPKGRTreeEntry>  m_aoRTreeEntries{};
471 
472 
473     virtual OGRErr      ResetStatement() override;
474 
475     void                BuildWhere();
476     OGRErr              RegisterGeometryColumn();
477 
478     CPLString           GetColumnsOfCreateTable(const std::vector<OGRFieldDefn*>& apoFields);
479     CPLString           BuildSelectFieldList(const std::vector<OGRFieldDefn*>& apoFields);
480     OGRErr              RecreateTable(const CPLString& osColumnsForCreate,
481                                       const CPLString& osFieldListForSelect);
482 #ifdef ENABLE_GPKG_OGR_CONTENTS
483     void                CreateTriggers(const char* pszTableName = nullptr);
484     void                DisableTriggers(bool bNullifyFeatureCount = true);
485 #endif
486 
487     void                CheckGeometryType( OGRFeature *poFeature );
488 
489     OGRErr              ReadTableDefinition();
490     void                InitView();
491 
492     bool                DoSpecialProcessingForColumnCreation(OGRFieldDefn* poField);
493 
494     bool                StartDeferredSpatialIndexUpdate();
495     bool                FlushPendingSpatialIndexUpdate();
496 
497     public:
498                         OGRGeoPackageTableLayer( GDALGeoPackageDataset *poDS,
499                                                  const char * pszTableName );
500                         virtual ~OGRGeoPackageTableLayer();
501 
502     /************************************************************************/
503     /* OGR API methods */
504 
GetName()505     const char*         GetName() override { return GetDescription(); }
506     const char*         GetFIDColumn() override;
507     OGRwkbGeometryType  GetGeomType() override;
508     const char*         GetGeometryColumn() override;
509     OGRFeatureDefn*     GetLayerDefn() override;
510     int                 TestCapability( const char * ) override;
511     OGRErr              CreateField( OGRFieldDefn *poField, int bApproxOK = TRUE ) override;
512     OGRErr              CreateGeomField( OGRGeomFieldDefn *poGeomFieldIn,
513                                          int bApproxOK = TRUE ) override;
514     virtual OGRErr      DeleteField(  int iFieldToDelete ) override;
515     virtual OGRErr      AlterFieldDefn( int iFieldToAlter, OGRFieldDefn* poNewFieldDefn, int nFlagsIn ) override;
516     virtual OGRErr      ReorderFields( int* panMap ) override;
517     void                ResetReading() override;
518     OGRErr              ICreateFeature( OGRFeature *poFeater ) override;
519     OGRErr              ISetFeature( OGRFeature *poFeature ) override;
520     OGRErr              DeleteFeature(GIntBig nFID) override;
521     virtual void        SetSpatialFilter( OGRGeometry * ) override;
SetSpatialFilter(int iGeomField,OGRGeometry * poGeom)522     virtual void        SetSpatialFilter( int iGeomField, OGRGeometry *poGeom ) override
523                 { OGRGeoPackageLayer::SetSpatialFilter(iGeomField, poGeom); }
524 
525     OGRErr              SetAttributeFilter( const char *pszQuery ) override;
526     OGRErr              SyncToDisk() override;
527     OGRFeature*         GetNextFeature() override;
528     OGRFeature*         GetFeature(GIntBig nFID) override;
529     OGRErr              StartTransaction() override;
530     OGRErr              CommitTransaction() override;
531     OGRErr              RollbackTransaction() override;
532     GIntBig             GetFeatureCount( int ) override;
533     OGRErr              GetExtent(OGREnvelope *psExtent, int bForce = TRUE) override;
GetExtent(int iGeomField,OGREnvelope * psExtent,int bForce)534     virtual OGRErr      GetExtent(int iGeomField, OGREnvelope *psExtent, int bForce) override
535                 { return OGRGeoPackageLayer::GetExtent(iGeomField, psExtent, bForce); }
536 
537     void                RecomputeExtent();
538 
539     void                SetOpeningParameters(bool bIsInGpkgContents,
540                                              bool bIsSpatial,
541                                              const char* pszGeomColName,
542                                              const char* pszGeomType,
543                                              bool bHasZ,
544                                              bool bHasM);
545     void                SetCreationParameters( OGRwkbGeometryType eGType,
546                                                const char* pszGeomColumnName,
547                                                int bGeomNullable,
548                                                OGRSpatialReference* poSRS,
549                                                const char* pszFIDColumnName,
550                                                const char* pszIdentifier,
551                                                const char* pszDescription );
SetDeferredSpatialIndexCreation(bool bFlag)552     void                SetDeferredSpatialIndexCreation( bool bFlag )
553                                 { m_bDeferredSpatialIndexCreation = bFlag; }
SetASpatialVariant(GPKGASpatialVariant eASpatialVariant)554     void                SetASpatialVariant( GPKGASpatialVariant eASpatialVariant )
555                                 { m_eASpatialVariant = eASpatialVariant; }
556 
557     void                CreateSpatialIndexIfNecessary();
558     bool                CreateSpatialIndex(const char* pszTableName = nullptr);
559     bool                DropSpatialIndex(bool bCalledFromSQLFunction = false);
560     CPLString           ReturnSQLCreateSpatialIndexTriggers(const char* pszTableName);
561     CPLString           ReturnSQLDropSpatialIndexTriggers();
562 
563     virtual char **     GetMetadata( const char *pszDomain = nullptr ) override;
564     virtual const char *GetMetadataItem( const char * pszName,
565                                              const char * pszDomain = "" ) override;
566     virtual char **     GetMetadataDomainList() override;
567 
568     virtual CPLErr      SetMetadata( char ** papszMetadata,
569                                         const char * pszDomain = "" ) override;
570     virtual CPLErr      SetMetadataItem( const char * pszName,
571                                             const char * pszValue,
572                                             const char * pszDomain = "" ) override;
573 
574     void                RenameTo(const char* pszDstTableName);
575 
576     virtual int          HasFastSpatialFilter(int iGeomCol) override;
577     virtual CPLString    GetSpatialWhere(int iGeomCol,
578                                          OGRGeometry* poFilterGeom) override;
579 
580     bool                HasSpatialIndex();
SetPrecisionFlag(int bFlag)581     void                SetPrecisionFlag( int bFlag )
582                                 { m_bPreservePrecision = CPL_TO_BOOL( bFlag ); }
SetTruncateFieldsFlag(int bFlag)583     void                SetTruncateFieldsFlag( int bFlag )
584                                 { m_bTruncateFields = CPL_TO_BOOL( bFlag ); }
585     OGRErr              RunDeferredCreationIfNecessary();
586     bool                RunDeferredDropRTreeTableIfNecessary();
587     bool                DoJobAtTransactionCommit();
588     bool                DoJobAtTransactionRollback();
589     bool                RunDeferredSpatialIndexUpdate();
590 
591 #ifdef ENABLE_GPKG_OGR_CONTENTS
GetAddOGRFeatureCountTriggers()592     bool                GetAddOGRFeatureCountTriggers() const
593                                     { return m_bAddOGRFeatureCountTriggers; }
SetAddOGRFeatureCountTriggers(bool b)594     void                SetAddOGRFeatureCountTriggers(bool b)
595                                     { m_bAddOGRFeatureCountTriggers = b; }
GetOGRFeatureCountTriggersDeletedInTransaction()596     bool                GetOGRFeatureCountTriggersDeletedInTransaction() const
597                         { return m_bFeatureCountTriggersDeletedInTransaction; }
SetOGRFeatureCountTriggersEnabled(bool b)598     void                SetOGRFeatureCountTriggersEnabled(bool b)
599                                     { m_bOGRFeatureCountTriggersEnabled = b; }
600 
601     void                DisableFeatureCount();
602 #endif
603 
604     /************************************************************************/
605     /* GPKG methods */
606 
607   private:
608     bool                CheckUpdatableTable(const char* pszOperation);
609     OGRErr              UpdateExtent( const OGREnvelope *poExtent );
610     OGRErr              SaveExtent();
611     OGRErr              SaveTimestamp();
612     OGRErr              BuildColumns();
613     bool                IsGeomFieldSet( OGRFeature *poFeature );
614     CPLString           FeatureGenerateUpdateSQL( OGRFeature *poFeature );
615     CPLString           FeatureGenerateInsertSQL( OGRFeature *poFeature, bool bAddFID, bool bBindUnsetFields );
616     OGRErr              FeatureBindUpdateParameters( OGRFeature *poFeature, sqlite3_stmt *poStmt );
617     OGRErr              FeatureBindInsertParameters( OGRFeature *poFeature, sqlite3_stmt *poStmt, bool bAddFID, bool bBindUnsetFields );
618     OGRErr              FeatureBindParameters( OGRFeature *poFeature, sqlite3_stmt *poStmt, int *pnColCount, bool bAddFID, bool bBindUnsetFields );
619     void                UpdateContentsToNullExtent();
620 
621     void                CheckUnknownExtensions();
622     bool                CreateGeometryExtensionIfNecessary(const OGRGeometry* poGeom);
623     bool                CreateGeometryExtensionIfNecessary(OGRwkbGeometryType eGType);
624 };
625 
626 /************************************************************************/
627 /*                         OGRGeoPackageSelectLayer                     */
628 /************************************************************************/
629 
630 class OGRGeoPackageSelectLayer final : public OGRGeoPackageLayer, public IOGRSQLiteSelectLayer
631 {
632     CPL_DISALLOW_COPY_ASSIGN(OGRGeoPackageSelectLayer)
633 
634     OGRSQLiteSelectLayerCommonBehaviour* poBehavior;
635 
636     virtual OGRErr      ResetStatement() override;
637 
638   public:
639                         OGRGeoPackageSelectLayer( GDALGeoPackageDataset *,
640                                               CPLString osSQL,
641                                               sqlite3_stmt *,
642                                               int bUseStatementForGetNextFeature,
643                                               int bEmptyLayer );
644                        virtual ~OGRGeoPackageSelectLayer();
645 
646     virtual void        ResetReading() override;
647 
648     virtual OGRFeature *GetNextFeature() override;
649     virtual GIntBig     GetFeatureCount( int ) override;
650 
SetSpatialFilter(OGRGeometry * poGeom)651     virtual void        SetSpatialFilter( OGRGeometry * poGeom ) override { SetSpatialFilter(0, poGeom); }
652     virtual void        SetSpatialFilter( int iGeomField, OGRGeometry * ) override;
653     virtual OGRErr      SetAttributeFilter( const char * ) override;
654 
655     virtual int         TestCapability( const char * ) override;
656 
657     virtual OGRErr      GetExtent(OGREnvelope *psExtent, int bForce = TRUE) override { return GetExtent(0, psExtent, bForce); }
658     virtual OGRErr      GetExtent(int iGeomField, OGREnvelope *psExtent, int bForce = TRUE) override;
659 
GetLayerDefn()660     virtual OGRFeatureDefn *     GetLayerDefn() override { return OGRGeoPackageLayer::GetLayerDefn(); }
GetAttrQueryString()661     virtual char*&               GetAttrQueryString() override { return m_pszAttrQueryString; }
GetFeatureQuery()662     virtual OGRFeatureQuery*&    GetFeatureQuery() override { return m_poAttrQuery; }
GetFilterGeom()663     virtual OGRGeometry*&        GetFilterGeom() override { return m_poFilterGeom; }
GetIGeomFieldFilter()664     virtual int&                 GetIGeomFieldFilter() override { return m_iGeomFieldFilter; }
GetSpatialRef()665     virtual OGRSpatialReference* GetSpatialRef() override { return OGRGeoPackageLayer::GetSpatialRef(); }
InstallFilter(OGRGeometry * poGeomIn)666     virtual int                  InstallFilter( OGRGeometry * poGeomIn ) override { return OGRGeoPackageLayer::InstallFilter(poGeomIn); }
HasReadFeature()667     virtual int                  HasReadFeature() override { return iNextShapeId > 0; }
BaseResetReading()668     virtual void                 BaseResetReading() override { OGRGeoPackageLayer::ResetReading(); }
BaseGetNextFeature()669     virtual OGRFeature          *BaseGetNextFeature() override { return OGRGeoPackageLayer::GetNextFeature(); }
BaseSetAttributeFilter(const char * pszQuery)670     virtual OGRErr               BaseSetAttributeFilter(const char* pszQuery) override { return OGRGeoPackageLayer::SetAttributeFilter(pszQuery); }
BaseGetFeatureCount(int bForce)671     virtual GIntBig              BaseGetFeatureCount(int bForce) override { return OGRGeoPackageLayer::GetFeatureCount(bForce); }
BaseTestCapability(const char * pszCap)672     virtual int                  BaseTestCapability( const char *pszCap ) override { return OGRGeoPackageLayer::TestCapability(pszCap); }
BaseGetExtent(OGREnvelope * psExtent,int bForce)673     virtual OGRErr               BaseGetExtent(OGREnvelope *psExtent, int bForce) override { return OGRGeoPackageLayer::GetExtent(psExtent, bForce); }
BaseGetExtent(int iGeomField,OGREnvelope * psExtent,int bForce)674     virtual OGRErr               BaseGetExtent(int iGeomField, OGREnvelope *psExtent, int bForce) override { return OGRGeoPackageLayer::GetExtent(iGeomField, psExtent, bForce); }
675 };
676 
677 #endif /* OGR_GEOPACKAGE_H_INCLUDED */
678