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: 2024-11-25 13:07:18 Functions: 11 13 84.6 %

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

Generated by: LCOV version 1.14