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