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