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: 2024-11-21 22:18:42 Functions: 32 32 100.0 %

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

Generated by: LCOV version 1.14