LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/sqlite - ogrsqlitebase.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 26 26 100.0 %
Date: 2025-01-18 12:42:00 Functions: 11 13 84.6 %

          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         926 :     OGRSQLiteGeomFieldDefn(const char *pszNameIn, int iGeomColIn)
      52         926 :         : OGRGeomFieldDefn(pszNameIn, wkbUnknown), m_iCol(iGeomColIn)
      53             :     {
      54         926 :     }
      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        3889 :     explicit OGRSQLiteFeatureDefn(const char *pszName = nullptr)
      75        3889 :         : OGRFeatureDefn(pszName)
      76             :     {
      77        3889 :         SetGeomType(wkbNone);
      78        3889 :     }
      79             : 
      80        7692 :     OGRSQLiteGeomFieldDefn *myGetGeomFieldDefn(int i)
      81             :     {
      82        7692 :         return cpl::down_cast<OGRSQLiteGeomFieldDefn *>(GetGeomFieldDefn(i));
      83             :     }
      84             : };
      85             : 
      86             : /************************************************************************/
      87             : /*                       IOGRSQLiteGetSpatialWhere                      */
      88             : /************************************************************************/
      89             : 
      90             : class IOGRSQLiteGetSpatialWhere
      91             : {
      92             :   public:
      93        8420 :     virtual ~IOGRSQLiteGetSpatialWhere()
      94        8420 :     {
      95        8420 :     }
      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        3550 : 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 bUserTransactionActive = FALSE;
     147             :     int nSoftTransactionLevel = 0;
     148             : 
     149             :     OGRErr DoTransactionCommand(const char *pszCommand);
     150             : 
     151             :     bool DealWithOgrSchemaOpenOption(CSLConstList papszOpenOptionsIn);
     152             : 
     153             :     CPL_DISALLOW_COPY_ASSIGN(OGRSQLiteBaseDataSource)
     154             : 
     155             :   public:
     156             :     OGRSQLiteBaseDataSource();
     157             :     virtual ~OGRSQLiteBaseDataSource();
     158             : 
     159      316688 :     sqlite3 *GetDB()
     160             :     {
     161      316688 :         return hDB;
     162             :     }
     163             : 
     164          72 :     sqlite3_vfs *GetVFS()
     165             :     {
     166          72 :         return pMyVFS;
     167             :     }
     168             : 
     169      296620 :     inline bool GetUpdate() const
     170             :     {
     171      296620 :         return eAccess == GA_Update;
     172             :     }
     173             : 
     174           3 :     VSILFILE *GetVSILFILE() const
     175             :     {
     176           3 :         return fpMainFile;
     177             :     }
     178             : 
     179             :     void NotifyFileOpened(const char *pszFilename, VSILFILE *fp);
     180             : 
     181             :     const OGREnvelope *GetEnvelopeFromSQL(const CPLString &osSQL);
     182             :     void SetEnvelopeForSQL(const CPLString &osSQL,
     183             :                            const OGREnvelope &oEnvelope);
     184             : 
     185             :     virtual std::pair<OGRLayer *, IOGRSQLiteGetSpatialWhere *>
     186             :     GetLayerWithGetSpatialWhereByName(const char *pszName) = 0;
     187             : 
     188             :     virtual OGRErr AbortSQL() override;
     189             :     bool SetQueryLoggerFunc(GDALQueryLoggerFunc pfnQueryLoggerFuncIn,
     190             :                             void *poQueryLoggerArgIn) override;
     191             : 
     192             :     virtual OGRErr StartTransaction(int bForce = FALSE) override;
     193             :     virtual OGRErr CommitTransaction() override;
     194             :     virtual OGRErr RollbackTransaction() override;
     195             : 
     196             :     virtual int TestCapability(const char *) override;
     197             : 
     198             :     virtual void *GetInternalHandle(const char *) override;
     199             : 
     200             :     OGRErr SoftStartTransaction();
     201             :     OGRErr SoftCommitTransaction();
     202             :     OGRErr SoftRollbackTransaction();
     203             : 
     204             :     OGRErr PragmaCheck(const char *pszPragma, const char *pszExpected,
     205             :                        int nRowsExpected);
     206             : 
     207             :     virtual void LoadRelationships() const;
     208             :     void LoadRelationshipsFromForeignKeys(
     209             :         const std::vector<std::string> &excludedTables) const;
     210             :     std::vector<std::string>
     211             :     GetRelationshipNames(CSLConstList papszOptions = nullptr) const override;
     212             :     const GDALRelationship *
     213             :     GetRelationship(const std::string &name) const override;
     214             : 
     215             :     bool IsSpatialiteLoaded();
     216             : 
     217       12108 :     static int MakeSpatialiteVersionNumber(int x, int y, int z)
     218             :     {
     219       12108 :         return x * 10000 + y * 100 + z;
     220             :     }
     221             : 
     222             :     int GetSpatialiteVersionNumber();
     223             : 
     224             :     bool SpatialiteRequiresTrustedSchemaOn();
     225             :     bool AreSpatialiteTriggersSafe();
     226             : 
     227             :     // sqlite3_prepare_v2 error logging wrapper
     228             :     int
     229             :     prepareSql(sqlite3 *db,           /* Database handle */
     230             :                const char *zSql,      /* SQL statement, UTF-8 encoded */
     231             :                int nByte,             /* Maximum length of zSql in bytes. */
     232             :                sqlite3_stmt **ppStmt, /* OUT: Statement handle */
     233             :                const char **pzTail /* OUT: Pointer to unused portion of zSql */
     234             :     );
     235             : 
     236             :     GDALQueryLoggerFunc pfnQueryLoggerFunc = nullptr;
     237             :     void *poQueryLoggerArg = nullptr;
     238             : };
     239             : 
     240             : /************************************************************************/
     241             : /*                         IOGRSQLiteSelectLayer                        */
     242             : /************************************************************************/
     243             : 
     244             : class IOGRSQLiteSelectLayer
     245             : {
     246             :   public:
     247        2340 :     virtual ~IOGRSQLiteSelectLayer()
     248        2340 :     {
     249        2340 :     }
     250             : 
     251             :     virtual char *&GetAttrQueryString() = 0;
     252             :     virtual OGRFeatureQuery *&GetFeatureQuery() = 0;
     253             :     virtual OGRGeometry *&GetFilterGeom() = 0;
     254             :     virtual int &GetIGeomFieldFilter() = 0;
     255             :     virtual OGRSpatialReference *GetSpatialRef() = 0;
     256             :     virtual OGRFeatureDefn *GetLayerDefn() = 0;
     257             :     virtual int InstallFilter(OGRGeometry *) = 0;
     258             :     virtual int HasReadFeature() = 0;
     259             :     virtual void BaseResetReading() = 0;
     260             :     virtual OGRFeature *BaseGetNextFeature() = 0;
     261             :     virtual OGRErr BaseSetAttributeFilter(const char *pszQuery) = 0;
     262             :     virtual GIntBig BaseGetFeatureCount(int bForce) = 0;
     263             :     virtual int BaseTestCapability(const char *) = 0;
     264             :     virtual OGRErr BaseGetExtent(OGREnvelope *psExtent, int bForce) = 0;
     265             :     virtual OGRErr BaseGetExtent(int iGeomField, OGREnvelope *psExtent,
     266             :                                  int bForce) = 0;
     267             :     virtual bool ValidateGeometryFieldIndexForSetSpatialFilter(
     268             :         int iGeomField, const OGRGeometry *poGeomIn, bool bIsSelectLayer) = 0;
     269             : };
     270             : 
     271             : /************************************************************************/
     272             : /*                   OGRSQLiteSelectLayerCommonBehaviour                */
     273             : /************************************************************************/
     274             : 
     275             : class OGRSQLiteSelectLayerCommonBehaviour
     276             : {
     277             :     OGRSQLiteBaseDataSource *m_poDS = nullptr;
     278             :     IOGRSQLiteSelectLayer *m_poLayer = nullptr;
     279             : 
     280             :     CPLString m_osSQLBase{};
     281             : 
     282             :     bool m_bEmptyLayer = false;
     283             :     bool m_bAllowResetReadingEvenIfIndexAtZero = false;
     284             :     bool m_bSpatialFilterInSQL = true;
     285             : 
     286             :     std::pair<OGRLayer *, IOGRSQLiteGetSpatialWhere *> GetBaseLayer(size_t &i);
     287             :     int BuildSQL();
     288             : 
     289             :     CPL_DISALLOW_COPY_ASSIGN(OGRSQLiteSelectLayerCommonBehaviour)
     290             : 
     291             :   public:
     292             :     CPLString m_osSQLCurrent{};
     293             : 
     294             :     OGRSQLiteSelectLayerCommonBehaviour(OGRSQLiteBaseDataSource *poDS,
     295             :                                         IOGRSQLiteSelectLayer *poBaseLayer,
     296             :                                         const CPLString &osSQL,
     297             :                                         bool bEmptyLayer);
     298             : 
     299             :     void ResetReading();
     300             :     OGRFeature *GetNextFeature();
     301             :     GIntBig GetFeatureCount(int);
     302             :     void SetSpatialFilter(int iGeomField, OGRGeometry *);
     303             :     OGRErr SetAttributeFilter(const char *);
     304             :     int TestCapability(const char *);
     305             :     OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent, int bForce);
     306             : };
     307             : 
     308             : /************************************************************************/
     309             : /*                   OGRSQLiteSingleFeatureLayer                        */
     310             : /************************************************************************/
     311             : 
     312             : class OGRSQLiteSingleFeatureLayer final : public OGRLayer
     313             : {
     314             :   private:
     315             :     int nVal;
     316             :     char *pszVal;
     317             :     OGRFeatureDefn *poFeatureDefn;
     318             :     int iNextShapeId;
     319             : 
     320             :     CPL_DISALLOW_COPY_ASSIGN(OGRSQLiteSingleFeatureLayer)
     321             : 
     322             :   public:
     323             :     OGRSQLiteSingleFeatureLayer(const char *pszLayerName, int nVal);
     324             :     OGRSQLiteSingleFeatureLayer(const char *pszLayerName, const char *pszVal);
     325             :     virtual ~OGRSQLiteSingleFeatureLayer();
     326             : 
     327             :     virtual void ResetReading() override;
     328             :     virtual OGRFeature *GetNextFeature() override;
     329             :     virtual OGRFeatureDefn *GetLayerDefn() override;
     330             :     virtual int TestCapability(const char *) override;
     331             : };
     332             : 
     333             : /************************************************************************/
     334             : /* Functions                                                            */
     335             : /************************************************************************/
     336             : 
     337             : OGRErr OGRSQLiteGetSpatialiteGeometryHeader(const GByte *pabyData, int nBytes,
     338             :                                             int *pnSRID,
     339             :                                             OGRwkbGeometryType *peType,
     340             :                                             bool *pbIsEmpty, double *pdfMinX,
     341             :                                             double *pdfMinY, double *pdfMaxX,
     342             :                                             double *pdfMaxY);
     343             : // CPL_DLL just for spatialite_geom_import_fuzzer
     344             : OGRErr CPL_DLL OGRSQLiteImportSpatiaLiteGeometry(const GByte *, int,
     345             :                                                  OGRGeometry **,
     346             :                                                  int *pnSRID = nullptr);
     347             : OGRErr OGRSQLiteExportSpatiaLiteGeometry(const OGRGeometry *, GInt32,
     348             :                                          OGRwkbByteOrder, bool bSpatialite2D,
     349             :                                          bool bUseComprGeom, GByte **, int *);
     350             : #endif  // OGR_SQLITE_BASE_H_INCLUDED

Generated by: LCOV version 1.14