LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/sqlite - ogrsqlitebase.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 28 28 100.0 %
Date: 2025-02-20 10:14:44 Functions: 12 14 85.7 %

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

Generated by: LCOV version 1.14