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 */
|