LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/pg - ogr_pg.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 88 88 100.0 %
Date: 2025-01-18 12:42:00 Functions: 32 32 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Private definitions for OGR/PostgreSQL driver.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2000, Frank Warmerdam
       9             :  * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #ifndef OGR_PG_H_INCLUDED
      15             : #define OGR_PG_H_INCLUDED
      16             : 
      17             : #include "ogrsf_frmts.h"
      18             : #include "libpq-fe.h"
      19             : #include "cpl_string.h"
      20             : 
      21             : #include "ogrpgutility.h"
      22             : #include "ogr_pgdump.h"
      23             : 
      24             : #include <map>
      25             : #include <optional>
      26             : #include <vector>
      27             : 
      28             : /* These are the OIDs for some builtin types, as returned by PQftype(). */
      29             : /* They were copied from pg_type.h in src/include/catalog/pg_type.h */
      30             : 
      31             : #define BOOLOID 16
      32             : #define BYTEAOID 17
      33             : #define CHAROID 18
      34             : #define NAMEOID 19
      35             : #define INT8OID 20
      36             : #define INT2OID 21
      37             : #define INT2VECTOROID 22
      38             : #define INT4OID 23
      39             : #define REGPROCOID 24
      40             : #define TEXTOID 25
      41             : #define OIDOID 26
      42             : #define TIDOID 27
      43             : #define XIDOID 28
      44             : #define CIDOID 29
      45             : #define OIDVECTOROID 30
      46             : #define JSONOID 114
      47             : #define FLOAT4OID 700
      48             : #define FLOAT8OID 701
      49             : #define BOOLARRAYOID 1000
      50             : #define INT2ARRAYOID 1005
      51             : #define INT4ARRAYOID 1007
      52             : #define TEXTARRAYOID 1009
      53             : #define BPCHARARRAYOID 1014
      54             : #define VARCHARARRAYOID 1015
      55             : #define INT8ARRAYOID 1016
      56             : #define FLOAT4ARRAYOID 1021
      57             : #define FLOAT8ARRAYOID 1022
      58             : #define BPCHAROID 1042
      59             : #define VARCHAROID 1043
      60             : #define DATEOID 1082
      61             : #define TIMEOID 1083
      62             : #define TIMESTAMPOID 1114
      63             : #define TIMESTAMPTZOID 1184
      64             : #define NUMERICOID 1700
      65             : #define NUMERICARRAYOID 1231
      66             : #define UUIDOID 2950
      67             : #define JSONBOID 3802
      68             : 
      69             : CPLString OGRPGEscapeString(void *hPGConn, const char *pszStrValue,
      70             :                             int nMaxLength = -1, const char *pszTableName = "",
      71             :                             const char *pszFieldName = "");
      72             : CPLString OGRPGEscapeColumnName(const char *pszColumnName);
      73             : 
      74             : #define UNDETERMINED_SRID                                                      \
      75             :     -2 /* Special value when we haven't yet looked for SRID */
      76             : 
      77             : class OGRPGDataSource;
      78             : class OGRPGLayer;
      79             : 
      80             : typedef enum
      81             : {
      82             :     GEOM_TYPE_UNKNOWN = 0,
      83             :     GEOM_TYPE_GEOMETRY = 1,
      84             :     GEOM_TYPE_GEOGRAPHY = 2,
      85             :     GEOM_TYPE_WKB = 3
      86             : } PostgisType;
      87             : 
      88             : typedef struct
      89             : {
      90             :     char *pszName;
      91             :     char *pszGeomType;
      92             :     int GeometryTypeFlags;
      93             :     int nSRID;
      94             :     PostgisType ePostgisType;
      95             :     int bNullable;
      96             : } PGGeomColumnDesc;
      97             : 
      98             : /************************************************************************/
      99             : /*                         OGRPGGeomFieldDefn                           */
     100             : /************************************************************************/
     101             : 
     102             : class OGRPGGeomFieldDefn final : public OGRGeomFieldDefn
     103             : {
     104             :     OGRPGGeomFieldDefn(const OGRPGGeomFieldDefn &) = delete;
     105             :     OGRPGGeomFieldDefn &operator=(const OGRPGGeomFieldDefn &) = delete;
     106             : 
     107             :   protected:
     108             :     OGRPGLayer *poLayer;
     109             : 
     110             :   public:
     111         562 :     OGRPGGeomFieldDefn(OGRPGLayer *poLayerIn, const char *pszFieldName)
     112         562 :         : OGRGeomFieldDefn(pszFieldName, wkbUnknown), poLayer(poLayerIn),
     113             :           nSRSId(UNDETERMINED_SRID), GeometryTypeFlags(0),
     114         562 :           ePostgisType(GEOM_TYPE_UNKNOWN)
     115             :     {
     116         562 :     }
     117             : 
     118             :     virtual const OGRSpatialReference *GetSpatialRef() const override;
     119             : 
     120         562 :     void UnsetLayer()
     121             :     {
     122         562 :         poLayer = nullptr;
     123         562 :     }
     124             : 
     125             :     mutable int nSRSId;
     126             :     mutable int GeometryTypeFlags;
     127             :     mutable PostgisType ePostgisType;
     128             : };
     129             : 
     130             : /************************************************************************/
     131             : /*                          OGRPGFeatureDefn                            */
     132             : /************************************************************************/
     133             : 
     134             : class OGRPGFeatureDefn CPL_NON_FINAL : public OGRFeatureDefn
     135             : {
     136             :   public:
     137         947 :     explicit OGRPGFeatureDefn(const char *pszName = nullptr)
     138         947 :         : OGRFeatureDefn(pszName)
     139             :     {
     140         947 :         SetGeomType(wkbNone);
     141         947 :     }
     142             : 
     143         947 :     virtual void UnsetLayer()
     144             :     {
     145         947 :         const int nGeomFieldCount = GetGeomFieldCount();
     146        1509 :         for (int i = 0; i < nGeomFieldCount; i++)
     147         562 :             cpl::down_cast<OGRPGGeomFieldDefn *>(apoGeomFieldDefn[i].get())
     148         562 :                 ->UnsetLayer();
     149         947 :     }
     150             : 
     151       22728 :     OGRPGGeomFieldDefn *GetGeomFieldDefn(int i) override
     152             :     {
     153       22728 :         return cpl::down_cast<OGRPGGeomFieldDefn *>(
     154       22728 :             OGRFeatureDefn::GetGeomFieldDefn(i));
     155             :     }
     156             : 
     157        1531 :     const OGRPGGeomFieldDefn *GetGeomFieldDefn(int i) const override
     158             :     {
     159        1531 :         return cpl::down_cast<const OGRPGGeomFieldDefn *>(
     160        1531 :             OGRFeatureDefn::GetGeomFieldDefn(i));
     161             :     }
     162             : };
     163             : 
     164             : /************************************************************************/
     165             : /*                            OGRPGLayer                                */
     166             : /************************************************************************/
     167             : 
     168             : class OGRPGLayer CPL_NON_FINAL : public OGRLayer
     169             : {
     170             :     OGRPGLayer(const OGRPGLayer &) = delete;
     171             :     OGRPGLayer &operator=(const OGRPGLayer &) = delete;
     172             : 
     173             :   protected:
     174             :     OGRPGFeatureDefn *poFeatureDefn = nullptr;
     175             : 
     176             :     int nCursorPage = 0;
     177             :     GIntBig iNextShapeId = 0;
     178             : 
     179             :     static char *GeometryToBYTEA(const OGRGeometry *, int nPostGISMajor,
     180             :                                  int nPostGISMinor);
     181             :     static GByte *BYTEAToGByteArray(const char *pszBytea, int *pnLength);
     182             :     static OGRGeometry *BYTEAToGeometry(const char *);
     183             :     Oid GeometryToOID(OGRGeometry *);
     184             :     OGRGeometry *OIDToGeometry(Oid);
     185             : 
     186             :     OGRPGDataSource *poDS = nullptr;
     187             : 
     188             :     char *pszQueryStatement = nullptr;
     189             : 
     190             :     char *pszCursorName = nullptr;
     191             :     PGresult *hCursorResult = nullptr;
     192             :     int bInvalidated = false;
     193             : 
     194             :     int nResultOffset = 0;
     195             : 
     196             :     int bWkbAsOid = false;
     197             : 
     198             :     char *pszFIDColumn = nullptr;
     199             : 
     200             :     int bCanUseBinaryCursor = true;
     201             :     int *m_panMapFieldNameToIndex = nullptr;
     202             :     int *m_panMapFieldNameToGeomIndex = nullptr;
     203             : 
     204             :     int ParsePGDate(const char *, OGRField *);
     205             : 
     206             :     void SetInitialQueryCursor();
     207             :     void CloseCursor();
     208             : 
     209             :     virtual CPLString GetFromClauseForGetExtent() = 0;
     210             :     OGRErr RunGetExtentRequest(OGREnvelope &sExtent, int bForce,
     211             :                                const std::string &osCommand, int bErrorAsDebug);
     212             :     OGRErr RunGetExtent3DRequest(OGREnvelope3D &sExtent3D,
     213             :                                  const std::string &osCommand,
     214             :                                  int bErrorAsDebug);
     215             :     static void CreateMapFromFieldNameToIndex(PGresult *hResult,
     216             :                                               OGRFeatureDefn *poFeatureDefn,
     217             :                                               int *&panMapFieldNameToIndex,
     218             :                                               int *&panMapFieldNameToGeomIndex);
     219             : 
     220             :     int ReadResultDefinition(PGresult *hInitialResultIn);
     221             : 
     222             :     OGRFeature *RecordToFeature(PGresult *hResult,
     223             :                                 const int *panMapFieldNameToIndex,
     224             :                                 const int *panMapFieldNameToGeomIndex,
     225             :                                 int iRecord);
     226             :     OGRFeature *GetNextRawFeature();
     227             : 
     228             :   public:
     229             :     OGRPGLayer();
     230             :     virtual ~OGRPGLayer();
     231             : 
     232             :     virtual void ResetReading() override;
     233             : 
     234       12279 :     virtual OGRPGFeatureDefn *GetLayerDefn() override
     235             :     {
     236       12279 :         return poFeatureDefn;
     237             :     }
     238             : 
     239           3 :     virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce) override
     240             :     {
     241           3 :         return GetExtent(0, psExtent, bForce);
     242             :     }
     243             : 
     244             :     virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
     245             :                              int bForce) override;
     246             : 
     247             :     OGRErr GetExtent3D(int iGeomField, OGREnvelope3D *psExtent3D,
     248             :                        int bForce) override;
     249             : 
     250             :     virtual OGRErr StartTransaction() override;
     251             :     virtual OGRErr CommitTransaction() override;
     252             :     virtual OGRErr RollbackTransaction() override;
     253             : 
     254             :     void InvalidateCursor();
     255             : 
     256             :     virtual const char *GetFIDColumn() override;
     257             : 
     258             :     virtual OGRErr SetNextByIndex(GIntBig nIndex) override;
     259             : 
     260          33 :     OGRPGDataSource *GetDS()
     261             :     {
     262          33 :         return poDS;
     263             :     }
     264             : 
     265             :     GDALDataset *GetDataset() override;
     266             : 
     267             :     virtual void ResolveSRID(const OGRPGGeomFieldDefn *poGFldDefn) = 0;
     268             : };
     269             : 
     270             : /************************************************************************/
     271             : /*                           OGRPGTableLayer                            */
     272             : /************************************************************************/
     273             : 
     274             : class OGRPGTableLayer final : public OGRPGLayer
     275             : {
     276             :     OGRPGTableLayer(const OGRPGTableLayer &) = delete;
     277             :     OGRPGTableLayer &operator=(const OGRPGTableLayer &) = delete;
     278             : 
     279             :     static constexpr int USE_COPY_UNSET = -10;
     280             : 
     281             :     int bUpdateAccess = false;
     282             : 
     283             :     void BuildWhere();
     284             :     CPLString BuildFields();
     285             :     void BuildFullQueryStatement();
     286             : 
     287             :     char *pszTableName = nullptr;
     288             :     char *pszSchemaName = nullptr;
     289             :     char *m_pszTableDescription = nullptr;
     290             :     CPLString osForcedDescription{};
     291             :     bool m_bMetadataLoaded = false;
     292             :     bool m_bMetadataModified = false;
     293             :     char *pszSqlTableName = nullptr;
     294             :     int bTableDefinitionValid = -1;
     295             : 
     296             :     CPLString osPrimaryKey{};
     297             : 
     298             :     int bGeometryInformationSet = false;
     299             : 
     300             :     /* Name of the parent table with the geometry definition if it is a derived
     301             :      * table or NULL */
     302             :     char *pszSqlGeomParentTableName = nullptr;
     303             : 
     304             :     char *pszGeomColForced = nullptr;
     305             : 
     306             :     CPLString osQuery{};
     307             :     CPLString osWHERE{};
     308             : 
     309             :     int bLaunderColumnNames = true;
     310             :     bool m_bUTF8ToASCII = false;
     311             :     int bPreservePrecision = true;
     312             :     int bUseCopy = USE_COPY_UNSET;
     313             :     int bCopyActive = false;
     314             :     bool bFIDColumnInCopyFields = false;
     315             :     int bFirstInsertion = true;
     316             : 
     317             :     OGRErr CreateFeatureViaCopy(OGRFeature *poFeature);
     318             :     OGRErr CreateFeatureViaInsert(OGRFeature *poFeature);
     319             :     CPLString BuildCopyFields();
     320             : 
     321             :     int bHasWarnedIncompatibleGeom = false;
     322             :     void CheckGeomTypeCompatibility(int iGeomField, OGRGeometry *poGeom);
     323             : 
     324             :     int bRetrieveFID = true;
     325             :     int bSkipConflicts = false;
     326             :     int bHasWarnedAlreadySetFID = false;
     327             : 
     328             :     char **papszOverrideColumnTypes = nullptr;
     329             :     int nForcedSRSId = UNDETERMINED_SRID;
     330             :     int nForcedGeometryTypeFlags = -1;
     331             :     bool bCreateSpatialIndexFlag = true;
     332             :     CPLString osSpatialIndexType = "GIST";
     333             :     int bInResetReading = false;
     334             : 
     335             :     int bAutoFIDOnCreateViaCopy = false;
     336             :     int bUseCopyByDefault = false;
     337             :     bool bNeedToUpdateSequence = false;
     338             : 
     339             :     int bDeferredCreation = false;
     340             :     CPLString osCreateTable{};
     341             :     std::vector<std::string> m_aosDeferredCommentOnColumns{};
     342             : 
     343             :     int iFIDAsRegularColumnIndex = -1;
     344             : 
     345             :     CPLString m_osFirstGeometryFieldName{};
     346             : 
     347             :     std::vector<bool> m_abGeneratedColumns{};
     348             : 
     349             :     std::string m_osLCOGeomType{};
     350             : 
     351          17 :     virtual CPLString GetFromClauseForGetExtent() override
     352             :     {
     353          17 :         return pszSqlTableName;
     354             :     }
     355             : 
     356             :     OGRErr RunAddGeometryColumn(const OGRPGGeomFieldDefn *poGeomField);
     357             :     OGRErr RunCreateSpatialIndex(const OGRPGGeomFieldDefn *poGeomField,
     358             :                                  int nIdx);
     359             : 
     360             :     void UpdateSequenceIfNeeded();
     361             : 
     362             :     void LoadMetadata();
     363             :     void SerializeMetadata();
     364             : 
     365             :   public:
     366             :     OGRPGTableLayer(OGRPGDataSource *, CPLString &osCurrentSchema,
     367             :                     const char *pszTableName, const char *pszSchemaName,
     368             :                     const char *pszDescriptionIn, const char *pszGeomColForced,
     369             :                     int bUpdate);
     370             :     virtual ~OGRPGTableLayer();
     371             : 
     372             :     void SetGeometryInformation(PGGeomColumnDesc *pasDesc, int nGeomFieldCount);
     373             : 
     374             :     virtual OGRFeature *GetFeature(GIntBig nFeatureId) override;
     375             :     virtual void ResetReading() override;
     376             :     virtual OGRFeature *GetNextFeature() override;
     377             :     virtual GIntBig GetFeatureCount(int) override;
     378             : 
     379          56 :     virtual void SetSpatialFilter(OGRGeometry *poGeom) override
     380             :     {
     381          56 :         SetSpatialFilter(0, poGeom);
     382          56 :     }
     383             : 
     384             :     virtual void SetSpatialFilter(int iGeomField, OGRGeometry *poGeom) override;
     385             : 
     386             :     virtual OGRErr SetAttributeFilter(const char *) override;
     387             : 
     388             :     virtual OGRErr ISetFeature(OGRFeature *poFeature) override;
     389             :     OGRErr IUpdateFeature(OGRFeature *poFeature, int nUpdatedFieldsCount,
     390             :                           const int *panUpdatedFieldsIdx,
     391             :                           int nUpdatedGeomFieldsCount,
     392             :                           const int *panUpdatedGeomFieldsIdx,
     393             :                           bool bUpdateStyleString) override;
     394             :     virtual OGRErr DeleteFeature(GIntBig nFID) override;
     395             :     virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
     396             : 
     397             :     virtual OGRErr CreateField(const OGRFieldDefn *poField,
     398             :                                int bApproxOK = TRUE) override;
     399             :     virtual OGRErr CreateGeomField(const OGRGeomFieldDefn *poGeomField,
     400             :                                    int bApproxOK = TRUE) override;
     401             :     virtual OGRErr DeleteField(int iField) override;
     402             :     virtual OGRErr AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
     403             :                                   int nFlags) override;
     404             :     virtual OGRErr
     405             :     AlterGeomFieldDefn(int iGeomFieldToAlter,
     406             :                        const OGRGeomFieldDefn *poNewGeomFieldDefn,
     407             :                        int nFlagsIn) override;
     408             : 
     409             :     virtual int TestCapability(const char *) override;
     410             : 
     411           8 :     virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce) override
     412             :     {
     413           8 :         return GetExtent(0, psExtent, bForce);
     414             :     }
     415             : 
     416             :     virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
     417             :                              int bForce) override;
     418             : 
     419          24 :     const char *GetTableName()
     420             :     {
     421          24 :         return pszTableName;
     422             :     }
     423             : 
     424          24 :     const char *GetSchemaName()
     425             :     {
     426          24 :         return pszSchemaName;
     427             :     }
     428             : 
     429             :     virtual const char *GetFIDColumn() override;
     430             : 
     431             :     virtual char **GetMetadataDomainList() override;
     432             :     virtual char **GetMetadata(const char *pszDomain = "") override;
     433             :     virtual const char *GetMetadataItem(const char *pszName,
     434             :                                         const char *pszDomain = "") override;
     435             :     virtual CPLErr SetMetadata(char **papszMD,
     436             :                                const char *pszDomain = "") override;
     437             :     virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
     438             :                                    const char *pszDomain = "") override;
     439             : 
     440             :     virtual OGRErr Rename(const char *pszNewName) override;
     441             : 
     442             :     OGRGeometryTypeCounter *GetGeometryTypes(int iGeomField, int nFlagsGGT,
     443             :                                              int &nEntryCountOut,
     444             :                                              GDALProgressFunc pfnProgress,
     445             :                                              void *pProgressData) override;
     446             : 
     447             :     int FindFieldIndex(const char *pszFieldName, int bExactMatch) override;
     448             : 
     449             :     // follow methods are not base class overrides
     450         223 :     void SetLaunderFlag(int bFlag)
     451             :     {
     452         223 :         bLaunderColumnNames = bFlag;
     453         223 :     }
     454             : 
     455         223 :     void SetUTF8ToASCIIFlag(bool bFlag)
     456             :     {
     457         223 :         m_bUTF8ToASCII = bFlag;
     458         223 :     }
     459             : 
     460         223 :     void SetPrecisionFlag(int bFlag)
     461             :     {
     462         223 :         bPreservePrecision = bFlag;
     463         223 :     }
     464             : 
     465             :     void SetOverrideColumnTypes(const char *pszOverrideColumnTypes);
     466             : 
     467             :     OGRErr StartCopy();
     468             :     OGRErr EndCopy();
     469             : 
     470             :     int ReadTableDefinition();
     471             : 
     472       72586 :     int HasGeometryInformation()
     473             :     {
     474       72586 :         return bGeometryInformationSet;
     475             :     }
     476             : 
     477             :     void SetTableDefinition(const char *pszFIDColumnName,
     478             :                             const char *pszGFldName, OGRwkbGeometryType eType,
     479             :                             const char *pszGeomType, int nSRSId,
     480             :                             int GeometryTypeFlags);
     481             : 
     482             :     void SetForcedSRSId(int nForcedSRSIdIn)
     483             :     {
     484             :         nForcedSRSId = nForcedSRSIdIn;
     485             :     }
     486             : 
     487         223 :     void SetForcedGeometryTypeFlags(int GeometryTypeFlagsIn)
     488             :     {
     489         223 :         nForcedGeometryTypeFlags = GeometryTypeFlagsIn;
     490         223 :     }
     491             : 
     492         223 :     void SetCreateSpatialIndex(bool bFlag, const char *pszSpatialIndexType)
     493             :     {
     494         223 :         bCreateSpatialIndexFlag = bFlag;
     495         223 :         osSpatialIndexType = pszSpatialIndexType;
     496         223 :     }
     497             : 
     498             :     void SetForcedDescription(const char *pszDescriptionIn);
     499             : 
     500         223 :     void AllowAutoFIDOnCreateViaCopy()
     501             :     {
     502         223 :         bAutoFIDOnCreateViaCopy = TRUE;
     503         223 :     }
     504             : 
     505         217 :     void SetUseCopy()
     506             :     {
     507         217 :         bUseCopy = TRUE;
     508         217 :         bUseCopyByDefault = TRUE;
     509         217 :     }
     510             : 
     511             :     void SetDeferredCreation(int bDeferredCreationIn,
     512             :                              const std::string &osCreateTable);
     513             :     OGRErr RunDeferredCreationIfNecessary();
     514             : 
     515             :     virtual void ResolveSRID(const OGRPGGeomFieldDefn *poGFldDefn) override;
     516             : };
     517             : 
     518             : /************************************************************************/
     519             : /*                           OGRPGResultLayer                           */
     520             : /************************************************************************/
     521             : 
     522             : class OGRPGResultLayer final : public OGRPGLayer
     523             : {
     524             :     OGRPGResultLayer(const OGRPGResultLayer &) = delete;
     525             :     OGRPGResultLayer &operator=(const OGRPGResultLayer &) = delete;
     526             : 
     527             :     void BuildFullQueryStatement();
     528             : 
     529             :     char *pszRawStatement = nullptr;
     530             : 
     531             :     char *pszGeomTableName = nullptr;
     532             :     char *pszGeomTableSchemaName = nullptr;
     533             : 
     534             :     CPLString osWHERE{};
     535             : 
     536           6 :     virtual CPLString GetFromClauseForGetExtent() override
     537             :     {
     538           6 :         CPLString osStr("(");
     539           6 :         osStr += pszRawStatement;
     540           6 :         osStr += ")";
     541           6 :         return osStr;
     542             :     }
     543             : 
     544             :   public:
     545             :     OGRPGResultLayer(OGRPGDataSource *, const char *pszRawStatement,
     546             :                      PGresult *hInitialResult);
     547             :     virtual ~OGRPGResultLayer();
     548             : 
     549             :     virtual void ResetReading() override;
     550             :     virtual GIntBig GetFeatureCount(int) override;
     551             : 
     552          27 :     virtual void SetSpatialFilter(OGRGeometry *poGeom) override
     553             :     {
     554          27 :         SetSpatialFilter(0, poGeom);
     555          27 :     }
     556             : 
     557             :     virtual void SetSpatialFilter(int iGeomField, OGRGeometry *poGeom) override;
     558             : 
     559             :     virtual int TestCapability(const char *) override;
     560             : 
     561             :     virtual OGRFeature *GetNextFeature() override;
     562             : 
     563             :     virtual void ResolveSRID(const OGRPGGeomFieldDefn *poGFldDefn) override;
     564             : };
     565             : 
     566             : /************************************************************************/
     567             : /*                           OGRPGDataSource                            */
     568             : /************************************************************************/
     569             : 
     570         428 : class OGRPGDataSource final : public GDALDataset
     571             : {
     572             :     OGRPGDataSource(const OGRPGDataSource &) = delete;
     573             :     OGRPGDataSource &operator=(const OGRPGDataSource &) = delete;
     574             : 
     575             :     typedef struct
     576             :     {
     577             :         int nMajor;
     578             :         int nMinor;
     579             :         int nRelease;
     580             :     } PGver;
     581             : 
     582             :     OGRPGTableLayer **papoLayers = nullptr;
     583             :     int nLayers = 0;
     584             : 
     585             :     bool m_bUTF8ClientEncoding = false;
     586             : 
     587             :     int bDSUpdate = false;
     588             :     int bHavePostGIS = false;
     589             :     int bHaveGeography = false;
     590             : 
     591             :     bool bUserTransactionActive = false;
     592             :     int bSavePointActive = false;
     593             :     int nSoftTransactionLevel = 0;
     594             : 
     595             :     PGconn *hPGConn = nullptr;
     596             : 
     597             :     OGRErr DeleteLayer(int iLayer) override;
     598             : 
     599             :     Oid nGeometryOID = static_cast<Oid>(0);
     600             :     Oid nGeographyOID = static_cast<Oid>(0);
     601             : 
     602             :     // We maintain a list of known SRID to reduce the number of trips to
     603             :     // the database to get SRSes.
     604             :     std::map<int,
     605             :              std::unique_ptr<OGRSpatialReference, OGRSpatialReferenceReleaser>>
     606             :         m_oSRSCache{};
     607             : 
     608             :     OGRPGTableLayer *poLayerInCopyMode = nullptr;
     609             : 
     610             :     static void OGRPGDecodeVersionString(PGver *psVersion, const char *pszVer);
     611             : 
     612             :     CPLString osCurrentSchema{};
     613             :     CPLString GetCurrentSchema();
     614             : 
     615             :     // Actual value will be auto-detected if PostGIS >= 2.0 detected.
     616             :     int nUndefinedSRID = -1;
     617             : 
     618             :     char *pszForcedTables = nullptr;
     619             :     char **papszSchemaList = nullptr;
     620             :     int bHasLoadTables = false;
     621             :     CPLString osActiveSchema{};
     622             :     int bListAllTables = false;
     623             :     bool m_bSkipViews = false;
     624             : 
     625             :     bool m_bOgrSystemTablesMetadataTableExistenceTested = false;
     626             :     bool m_bOgrSystemTablesMetadataTableFound = false;
     627             : 
     628             :     bool m_bCreateMetadataTableIfNeededRun = false;
     629             :     bool m_bCreateMetadataTableIfNeededSuccess = false;
     630             : 
     631             :     bool m_bHasWritePermissionsOnMetadataTableRun = false;
     632             :     bool m_bHasWritePermissionsOnMetadataTableSuccess = false;
     633             : 
     634             :     void LoadTables();
     635             : 
     636             :     CPLString osDebugLastTransactionCommand{};
     637             :     OGRErr DoTransactionCommand(const char *pszCommand);
     638             : 
     639             :     OGRErr FlushSoftTransaction();
     640             : 
     641             :     OGRErr FlushCacheWithRet(bool bAtClosing);
     642             : 
     643             :     std::optional<std::string> FindSchema(const char *pszSchemaNameIn);
     644             : 
     645             :     bool IsSuperUser();
     646             :     bool OGRSystemTablesEventTriggerExists();
     647             : 
     648             :   public:
     649             :     PGver sPostgreSQLVersion = {0, 0, 0};
     650             :     PGver sPostGISVersion = {0, 0, 0};
     651             : 
     652             :     int bUseBinaryCursor = false;
     653             :     int bBinaryTimeFormatIsInt8 = false;
     654             : 
     655             :     bool m_bHasGeometryColumns = false;
     656             :     bool m_bHasSpatialRefSys = false;
     657             : 
     658         745 :     bool HavePostGIS() const
     659             :     {
     660         745 :         return bHavePostGIS;
     661             :     }
     662             : 
     663         130 :     int GetUndefinedSRID() const
     664             :     {
     665         130 :         return nUndefinedSRID;
     666             :     }
     667             : 
     668        3739 :     bool IsUTF8ClientEncoding() const
     669             :     {
     670        3739 :         return m_bUTF8ClientEncoding;
     671             :     }
     672             : 
     673             :   public:
     674             :     OGRPGDataSource();
     675             :     virtual ~OGRPGDataSource();
     676             : 
     677      231945 :     PGconn *GetPGConn()
     678             :     {
     679      231945 :         return hPGConn;
     680             :     }
     681             : 
     682             :     int FetchSRSId(const OGRSpatialReference *poSRS);
     683             :     const OGRSpatialReference *FetchSRS(int nSRSId);
     684             :     static OGRErr InitializeMetadataTables();
     685             : 
     686             :     int Open(const char *, int bUpdate, int bTestOpen, char **papszOpenOptions);
     687             :     OGRPGTableLayer *
     688             :     OpenTable(CPLString &osCurrentSchema, const char *pszTableName,
     689             :               const char *pszSchemaName, const char *pszDescription,
     690             :               const char *pszGeomColForced, int bUpdate, int bTestOpen);
     691             : 
     692             :     int GetLayerCount() override;
     693             :     OGRLayer *GetLayer(int) override;
     694             :     OGRLayer *GetLayerByName(const char *pszName) override;
     695             : 
     696             :     virtual CPLErr FlushCache(bool bAtClosing) override;
     697             : 
     698             :     OGRLayer *ICreateLayer(const char *pszName,
     699             :                            const OGRGeomFieldDefn *poGeomFieldDefn,
     700             :                            CSLConstList papszOptions) override;
     701             : 
     702             :     int TestCapability(const char *) override;
     703             : 
     704             :     virtual OGRErr StartTransaction(int bForce = FALSE) override;
     705             :     virtual OGRErr CommitTransaction() override;
     706             :     virtual OGRErr RollbackTransaction() override;
     707             : 
     708             :     OGRErr SoftStartTransaction();
     709             :     OGRErr SoftCommitTransaction();
     710             :     OGRErr SoftRollbackTransaction();
     711             : 
     712         421 :     Oid GetGeometryOID()
     713             :     {
     714         421 :         return nGeometryOID;
     715             :     }
     716             : 
     717         471 :     Oid GetGeographyOID()
     718             :     {
     719         471 :         return nGeographyOID;
     720             :     }
     721             : 
     722             :     virtual OGRLayer *ExecuteSQL(const char *pszSQLCommand,
     723             :                                  OGRGeometry *poSpatialFilter,
     724             :                                  const char *pszDialect) override;
     725             :     virtual OGRErr AbortSQL() override;
     726             :     virtual void ReleaseResultSet(OGRLayer *poLayer) override;
     727             : 
     728             :     virtual const char *GetMetadataItem(const char *pszKey,
     729             :                                         const char *pszDomain) override;
     730             : 
     731             :     int UseCopy();
     732             :     void StartCopy(OGRPGTableLayer *poPGLayer);
     733             :     OGRErr EndCopy();
     734             : 
     735          16 :     bool IsUserTransactionActive()
     736             :     {
     737          16 :         return bUserTransactionActive;
     738             :     }
     739             : 
     740             :     bool CreateMetadataTableIfNeeded();
     741             :     bool HasOgrSystemTablesMetadataTable();
     742             :     bool HasWritePermissionsOnMetadataTable();
     743             : };
     744             : 
     745             : #endif /* ndef OGR_PG_H_INCLUDED */

Generated by: LCOV version 1.14