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 nMaxLengthUnused = -1,
71 : 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 564 : OGRPGGeomFieldDefn(OGRPGLayer *poLayerIn, const char *pszFieldName)
113 564 : : OGRGeomFieldDefn(pszFieldName, wkbUnknown), poLayer(poLayerIn),
114 : nSRSId(UNDETERMINED_SRID), GeometryTypeFlags(0),
115 564 : ePostgisType(GEOM_TYPE_UNKNOWN)
116 : {
117 564 : }
118 :
119 : virtual const OGRSpatialReference *GetSpatialRef() const override;
120 :
121 564 : void UnsetLayer()
122 : {
123 564 : poLayer = nullptr;
124 564 : }
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 951 : explicit OGRPGFeatureDefn(const char *pszName = nullptr)
139 951 : : OGRFeatureDefn(pszName)
140 : {
141 951 : SetGeomType(wkbNone);
142 951 : }
143 :
144 : virtual void UnsetLayer();
145 :
146 22554 : OGRPGGeomFieldDefn *GetGeomFieldDefn(int i) override
147 : {
148 22554 : return cpl::down_cast<OGRPGGeomFieldDefn *>(
149 22554 : OGRFeatureDefn::GetGeomFieldDefn(i));
150 : }
151 :
152 1533 : const OGRPGGeomFieldDefn *GetGeomFieldDefn(int i) const override
153 : {
154 1533 : return cpl::down_cast<const OGRPGGeomFieldDefn *>(
155 1533 : OGRFeatureDefn::GetGeomFieldDefn(i));
156 : }
157 : };
158 :
159 : /************************************************************************/
160 : /* OGRPGLayer */
161 : /************************************************************************/
162 :
163 : class OGRPGLayer CPL_NON_FINAL : public OGRLayer
164 : {
165 : OGRPGLayer(const OGRPGLayer &) = delete;
166 : OGRPGLayer &operator=(const OGRPGLayer &) = delete;
167 :
168 : protected:
169 : OGRPGFeatureDefn *poFeatureDefn = nullptr;
170 :
171 : int nCursorPage = 0;
172 : GIntBig iNextShapeId = 0;
173 :
174 : static char *GeometryToBYTEA(const OGRGeometry *, int nPostGISMajor,
175 : int nPostGISMinor);
176 : static GByte *BYTEAToGByteArray(const char *pszBytea, int *pnLength);
177 : static OGRGeometry *BYTEAToGeometry(const char *);
178 : Oid GeometryToOID(OGRGeometry *);
179 : OGRGeometry *OIDToGeometry(Oid);
180 :
181 : OGRPGDataSource *poDS = nullptr;
182 :
183 : char *pszQueryStatement = nullptr;
184 :
185 : char *pszCursorName = nullptr;
186 : PGresult *hCursorResult = nullptr;
187 : int bInvalidated = false;
188 :
189 : int nResultOffset = 0;
190 :
191 : int bWkbAsOid = false;
192 :
193 : char *pszFIDColumn = nullptr;
194 :
195 : int bCanUseBinaryCursor = true;
196 : int *m_panMapFieldNameToIndex = nullptr;
197 : int *m_panMapFieldNameToGeomIndex = nullptr;
198 :
199 : int ParsePGDate(const char *, OGRField *);
200 :
201 : void SetInitialQueryCursor();
202 : void CloseCursor();
203 :
204 : virtual CPLString GetFromClauseForGetExtent() = 0;
205 : OGRErr RunGetExtentRequest(OGREnvelope &sExtent, int bForce,
206 : const std::string &osCommand, int bErrorAsDebug);
207 : OGRErr RunGetExtent3DRequest(OGREnvelope3D &sExtent3D,
208 : const std::string &osCommand,
209 : int bErrorAsDebug);
210 : static void CreateMapFromFieldNameToIndex(PGresult *hResult,
211 : OGRFeatureDefn *poFeatureDefn,
212 : int *&panMapFieldNameToIndex,
213 : int *&panMapFieldNameToGeomIndex);
214 :
215 : int ReadResultDefinition(PGresult *hInitialResultIn);
216 :
217 : OGRFeature *RecordToFeature(PGresult *hResult,
218 : const int *panMapFieldNameToIndex,
219 : const int *panMapFieldNameToGeomIndex,
220 : int iRecord);
221 : OGRFeature *GetNextRawFeature();
222 :
223 : public:
224 : OGRPGLayer();
225 : virtual ~OGRPGLayer();
226 :
227 : virtual void ResetReading() override;
228 :
229 11977 : virtual OGRPGFeatureDefn *GetLayerDefn() override
230 : {
231 11977 : return poFeatureDefn;
232 : }
233 :
234 : OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
235 : bool bForce) override;
236 :
237 : OGRErr IGetExtent3D(int iGeomField, OGREnvelope3D *psExtent3D,
238 : bool bForce) override;
239 :
240 : virtual OGRErr StartTransaction() override;
241 : virtual OGRErr CommitTransaction() override;
242 : virtual OGRErr RollbackTransaction() override;
243 :
244 : void InvalidateCursor();
245 :
246 : virtual const char *GetFIDColumn() override;
247 :
248 : virtual OGRErr SetNextByIndex(GIntBig nIndex) override;
249 :
250 33 : OGRPGDataSource *GetDS()
251 : {
252 33 : return poDS;
253 : }
254 :
255 : GDALDataset *GetDataset() override;
256 :
257 : virtual void ResolveSRID(const OGRPGGeomFieldDefn *poGFldDefn) = 0;
258 : };
259 :
260 : /************************************************************************/
261 : /* OGRPGTableLayer */
262 : /************************************************************************/
263 :
264 : class OGRPGTableLayer final : public OGRPGLayer
265 : {
266 : OGRPGTableLayer(const OGRPGTableLayer &) = delete;
267 : OGRPGTableLayer &operator=(const OGRPGTableLayer &) = delete;
268 :
269 : static constexpr int USE_COPY_UNSET = -10;
270 :
271 : int bUpdateAccess = false;
272 :
273 : void BuildWhere();
274 : CPLString BuildFields();
275 : void BuildFullQueryStatement();
276 :
277 : char *pszTableName = nullptr;
278 : char *pszSchemaName = nullptr;
279 : char *m_pszTableDescription = nullptr;
280 : CPLString osForcedDescription{};
281 : bool m_bMetadataLoaded = false;
282 : bool m_bMetadataModified = false;
283 : char *pszSqlTableName = nullptr;
284 : int bTableDefinitionValid = -1;
285 :
286 : CPLString osPrimaryKey{};
287 :
288 : int bGeometryInformationSet = false;
289 :
290 : /* Name of the parent table with the geometry definition if it is a derived
291 : * table or NULL */
292 : char *pszSqlGeomParentTableName = nullptr;
293 :
294 : char *pszGeomColForced = nullptr;
295 :
296 : CPLString osQuery{};
297 : CPLString osWHERE{};
298 :
299 : int bLaunderColumnNames = true;
300 : bool m_bUTF8ToASCII = false;
301 : int bPreservePrecision = true;
302 : int bUseCopy = USE_COPY_UNSET;
303 : int bCopyActive = false;
304 : bool bFIDColumnInCopyFields = false;
305 : int bFirstInsertion = true;
306 :
307 : OGRErr CreateFeatureViaCopy(OGRFeature *poFeature);
308 : OGRErr CreateFeatureViaInsert(OGRFeature *poFeature);
309 : CPLString BuildCopyFields();
310 :
311 : int bHasWarnedIncompatibleGeom = false;
312 : void CheckGeomTypeCompatibility(int iGeomField, OGRGeometry *poGeom);
313 :
314 : int bRetrieveFID = true;
315 : int bSkipConflicts = false;
316 : int bHasWarnedAlreadySetFID = false;
317 :
318 : char **papszOverrideColumnTypes = nullptr;
319 : int nForcedSRSId = UNDETERMINED_SRID;
320 : int nForcedGeometryTypeFlags = -1;
321 : bool bCreateSpatialIndexFlag = true;
322 : CPLString osSpatialIndexType = "GIST";
323 : int bInResetReading = false;
324 :
325 : int bAutoFIDOnCreateViaCopy = false;
326 : int bUseCopyByDefault = false;
327 : bool bNeedToUpdateSequence = false;
328 :
329 : int bDeferredCreation = false;
330 : CPLString osCreateTable{};
331 : std::vector<std::string> m_aosDeferredCommentOnColumns{};
332 :
333 : int iFIDAsRegularColumnIndex = -1;
334 :
335 : CPLString m_osFirstGeometryFieldName{};
336 :
337 : std::string m_osLCOGeomType{};
338 :
339 17 : virtual CPLString GetFromClauseForGetExtent() override
340 : {
341 17 : return pszSqlTableName;
342 : }
343 :
344 : OGRErr RunAddGeometryColumn(const OGRPGGeomFieldDefn *poGeomField);
345 : OGRErr RunCreateSpatialIndex(const OGRPGGeomFieldDefn *poGeomField,
346 : int nIdx);
347 :
348 : void UpdateSequenceIfNeeded();
349 :
350 : void LoadMetadata();
351 : void SerializeMetadata();
352 :
353 : public:
354 : OGRPGTableLayer(OGRPGDataSource *, CPLString &osCurrentSchema,
355 : const char *pszTableName, const char *pszSchemaName,
356 : const char *pszDescriptionIn, const char *pszGeomColForced,
357 : int bUpdate);
358 : virtual ~OGRPGTableLayer();
359 :
360 : void SetGeometryInformation(PGGeomColumnDesc *pasDesc, int nGeomFieldCount);
361 :
362 : virtual OGRFeature *GetFeature(GIntBig nFeatureId) override;
363 : virtual void ResetReading() override;
364 : virtual OGRFeature *GetNextFeature() override;
365 : virtual GIntBig GetFeatureCount(int) override;
366 :
367 : OGRErr ISetSpatialFilter(int iGeomField,
368 : const OGRGeometry *poGeom) override;
369 :
370 : virtual OGRErr SetAttributeFilter(const char *) override;
371 :
372 : virtual OGRErr ISetFeature(OGRFeature *poFeature) override;
373 : OGRErr IUpdateFeature(OGRFeature *poFeature, int nUpdatedFieldsCount,
374 : const int *panUpdatedFieldsIdx,
375 : int nUpdatedGeomFieldsCount,
376 : const int *panUpdatedGeomFieldsIdx,
377 : bool bUpdateStyleString) override;
378 : virtual OGRErr DeleteFeature(GIntBig nFID) override;
379 : virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
380 :
381 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
382 : int bApproxOK = TRUE) override;
383 : virtual OGRErr CreateGeomField(const OGRGeomFieldDefn *poGeomField,
384 : int bApproxOK = TRUE) override;
385 : virtual OGRErr DeleteField(int iField) override;
386 : virtual OGRErr AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
387 : int nFlags) override;
388 : virtual OGRErr
389 : AlterGeomFieldDefn(int iGeomFieldToAlter,
390 : const OGRGeomFieldDefn *poNewGeomFieldDefn,
391 : int nFlagsIn) override;
392 :
393 : virtual int TestCapability(const char *) override;
394 :
395 : OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
396 : bool bForce) override;
397 :
398 24 : const char *GetTableName()
399 : {
400 24 : return pszTableName;
401 : }
402 :
403 24 : const char *GetSchemaName()
404 : {
405 24 : return pszSchemaName;
406 : }
407 :
408 : virtual const char *GetFIDColumn() override;
409 :
410 : virtual char **GetMetadataDomainList() override;
411 : virtual char **GetMetadata(const char *pszDomain = "") override;
412 : virtual const char *GetMetadataItem(const char *pszName,
413 : const char *pszDomain = "") override;
414 : virtual CPLErr SetMetadata(char **papszMD,
415 : const char *pszDomain = "") override;
416 : virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
417 : const char *pszDomain = "") override;
418 :
419 : virtual OGRErr Rename(const char *pszNewName) override;
420 :
421 : OGRGeometryTypeCounter *GetGeometryTypes(int iGeomField, int nFlagsGGT,
422 : int &nEntryCountOut,
423 : GDALProgressFunc pfnProgress,
424 : void *pProgressData) override;
425 :
426 : int FindFieldIndex(const char *pszFieldName, int bExactMatch) override;
427 :
428 : // follow methods are not base class overrides
429 225 : void SetLaunderFlag(int bFlag)
430 : {
431 225 : bLaunderColumnNames = bFlag;
432 225 : }
433 :
434 225 : void SetUTF8ToASCIIFlag(bool bFlag)
435 : {
436 225 : m_bUTF8ToASCII = bFlag;
437 225 : }
438 :
439 225 : void SetPrecisionFlag(int bFlag)
440 : {
441 225 : bPreservePrecision = bFlag;
442 225 : }
443 :
444 : void SetOverrideColumnTypes(const char *pszOverrideColumnTypes);
445 :
446 : OGRErr StartCopy();
447 : OGRErr EndCopy();
448 :
449 : int ReadTableDefinition();
450 :
451 72321 : int HasGeometryInformation()
452 : {
453 72321 : return bGeometryInformationSet;
454 : }
455 :
456 : void SetTableDefinition(const char *pszFIDColumnName,
457 : const char *pszGFldName, OGRwkbGeometryType eType,
458 : const char *pszGeomType, int nSRSId,
459 : int GeometryTypeFlags);
460 :
461 : void SetForcedSRSId(int nForcedSRSIdIn)
462 : {
463 : nForcedSRSId = nForcedSRSIdIn;
464 : }
465 :
466 225 : void SetForcedGeometryTypeFlags(int GeometryTypeFlagsIn)
467 : {
468 225 : nForcedGeometryTypeFlags = GeometryTypeFlagsIn;
469 225 : }
470 :
471 225 : void SetCreateSpatialIndex(bool bFlag, const char *pszSpatialIndexType)
472 : {
473 225 : bCreateSpatialIndexFlag = bFlag;
474 225 : osSpatialIndexType = pszSpatialIndexType;
475 225 : }
476 :
477 : void SetForcedDescription(const char *pszDescriptionIn);
478 :
479 225 : void AllowAutoFIDOnCreateViaCopy()
480 : {
481 225 : bAutoFIDOnCreateViaCopy = TRUE;
482 225 : }
483 :
484 219 : void SetUseCopy()
485 : {
486 219 : bUseCopy = TRUE;
487 219 : bUseCopyByDefault = TRUE;
488 219 : }
489 :
490 : void SetDeferredCreation(int bDeferredCreationIn,
491 : const std::string &osCreateTable);
492 : OGRErr RunDeferredCreationIfNecessary();
493 :
494 : virtual void ResolveSRID(const OGRPGGeomFieldDefn *poGFldDefn) override;
495 : };
496 :
497 : /************************************************************************/
498 : /* OGRPGResultLayer */
499 : /************************************************************************/
500 :
501 : class OGRPGResultLayer final : public OGRPGLayer
502 : {
503 : OGRPGResultLayer(const OGRPGResultLayer &) = delete;
504 : OGRPGResultLayer &operator=(const OGRPGResultLayer &) = delete;
505 :
506 : void BuildFullQueryStatement();
507 :
508 : char *pszRawStatement = nullptr;
509 :
510 : char *pszGeomTableName = nullptr;
511 : char *pszGeomTableSchemaName = nullptr;
512 :
513 : CPLString osWHERE{};
514 :
515 6 : virtual CPLString GetFromClauseForGetExtent() override
516 : {
517 6 : CPLString osStr("(");
518 6 : osStr += pszRawStatement;
519 6 : osStr += ")";
520 6 : return osStr;
521 : }
522 :
523 : public:
524 : OGRPGResultLayer(OGRPGDataSource *, const char *pszRawStatement,
525 : PGresult *hInitialResult);
526 : virtual ~OGRPGResultLayer();
527 :
528 : virtual void ResetReading() override;
529 : virtual GIntBig GetFeatureCount(int) override;
530 :
531 : OGRErr ISetSpatialFilter(int iGeomField,
532 : const OGRGeometry *poGeom) override;
533 :
534 : virtual int TestCapability(const char *) override;
535 :
536 : virtual OGRFeature *GetNextFeature() override;
537 :
538 : virtual void ResolveSRID(const OGRPGGeomFieldDefn *poGFldDefn) override;
539 : };
540 :
541 : /************************************************************************/
542 : /* OGRPGDataSource */
543 : /************************************************************************/
544 :
545 430 : class OGRPGDataSource final : public GDALDataset
546 : {
547 : OGRPGDataSource(const OGRPGDataSource &) = delete;
548 : OGRPGDataSource &operator=(const OGRPGDataSource &) = delete;
549 :
550 : typedef struct
551 : {
552 : int nMajor;
553 : int nMinor;
554 : int nRelease;
555 : } PGver;
556 :
557 : OGRPGTableLayer **papoLayers = nullptr;
558 : int nLayers = 0;
559 :
560 : bool m_bUTF8ClientEncoding = false;
561 :
562 : int bDSUpdate = false;
563 : int bHavePostGIS = false;
564 : int bHaveGeography = false;
565 :
566 : bool bUserTransactionActive = false;
567 : int bSavePointActive = false;
568 : int nSoftTransactionLevel = 0;
569 :
570 : PGconn *hPGConn = nullptr;
571 :
572 : OGRErr DeleteLayer(int iLayer) override;
573 :
574 : Oid nGeometryOID = static_cast<Oid>(0);
575 : Oid nGeographyOID = static_cast<Oid>(0);
576 :
577 : // We maintain a list of known SRID to reduce the number of trips to
578 : // the database to get SRSes.
579 : std::map<int,
580 : std::unique_ptr<OGRSpatialReference, OGRSpatialReferenceReleaser>>
581 : m_oSRSCache{};
582 :
583 : OGRPGTableLayer *poLayerInCopyMode = nullptr;
584 :
585 : static void OGRPGDecodeVersionString(PGver *psVersion, const char *pszVer);
586 :
587 : CPLString osCurrentSchema{};
588 : CPLString GetCurrentSchema();
589 :
590 : // Actual value will be auto-detected if PostGIS >= 2.0 detected.
591 : int nUndefinedSRID = -1;
592 :
593 : char *pszForcedTables = nullptr;
594 : char **papszSchemaList = nullptr;
595 : int bHasLoadTables = false;
596 : CPLString osActiveSchema{};
597 : int bListAllTables = false;
598 : bool m_bSkipViews = false;
599 :
600 : bool m_bOgrSystemTablesMetadataTableExistenceTested = false;
601 : bool m_bOgrSystemTablesMetadataTableFound = false;
602 :
603 : bool m_bCreateMetadataTableIfNeededRun = false;
604 : bool m_bCreateMetadataTableIfNeededSuccess = false;
605 :
606 : bool m_bHasWritePermissionsOnMetadataTableRun = false;
607 : bool m_bHasWritePermissionsOnMetadataTableSuccess = false;
608 :
609 : void LoadTables();
610 :
611 : CPLString osDebugLastTransactionCommand{};
612 : OGRErr DoTransactionCommand(const char *pszCommand);
613 :
614 : OGRErr FlushSoftTransaction();
615 :
616 : OGRErr FlushCacheWithRet(bool bAtClosing);
617 :
618 : std::optional<std::string> FindSchema(const char *pszSchemaNameIn);
619 :
620 : bool IsSuperUser();
621 : bool OGRSystemTablesEventTriggerExists();
622 :
623 : public:
624 : PGver sPostgreSQLVersion = {0, 0, 0};
625 : PGver sPostGISVersion = {0, 0, 0};
626 :
627 : int bUseBinaryCursor = false;
628 : int bBinaryTimeFormatIsInt8 = false;
629 :
630 : bool m_bHasGeometryColumns = false;
631 : bool m_bHasSpatialRefSys = false;
632 :
633 747 : bool HavePostGIS() const
634 : {
635 747 : return bHavePostGIS;
636 : }
637 :
638 130 : int GetUndefinedSRID() const
639 : {
640 130 : return nUndefinedSRID;
641 : }
642 :
643 3739 : bool IsUTF8ClientEncoding() const
644 : {
645 3739 : return m_bUTF8ClientEncoding;
646 : }
647 :
648 : public:
649 : OGRPGDataSource();
650 : virtual ~OGRPGDataSource();
651 :
652 248024 : PGconn *GetPGConn()
653 : {
654 248024 : return hPGConn;
655 : }
656 :
657 : int FetchSRSId(const OGRSpatialReference *poSRS);
658 : const OGRSpatialReference *FetchSRS(int nSRSId);
659 : static OGRErr InitializeMetadataTables();
660 :
661 : int Open(const char *, int bUpdate, int bTestOpen, char **papszOpenOptions);
662 : OGRPGTableLayer *
663 : OpenTable(CPLString &osCurrentSchema, const char *pszTableName,
664 : const char *pszSchemaName, const char *pszDescription,
665 : const char *pszGeomColForced, int bUpdate, int bTestOpen);
666 :
667 : int GetLayerCount() override;
668 : OGRLayer *GetLayer(int) override;
669 : OGRLayer *GetLayerByName(const char *pszName) override;
670 :
671 : virtual CPLErr FlushCache(bool bAtClosing) override;
672 :
673 : OGRLayer *ICreateLayer(const char *pszName,
674 : const OGRGeomFieldDefn *poGeomFieldDefn,
675 : CSLConstList papszOptions) override;
676 :
677 : int TestCapability(const char *) override;
678 :
679 : virtual OGRErr StartTransaction(int bForce = FALSE) override;
680 : virtual OGRErr CommitTransaction() override;
681 : virtual OGRErr RollbackTransaction() override;
682 :
683 : OGRErr SoftStartTransaction();
684 : OGRErr SoftCommitTransaction();
685 : OGRErr SoftRollbackTransaction();
686 :
687 421 : Oid GetGeometryOID()
688 : {
689 421 : return nGeometryOID;
690 : }
691 :
692 471 : Oid GetGeographyOID()
693 : {
694 471 : return nGeographyOID;
695 : }
696 :
697 : virtual OGRLayer *ExecuteSQL(const char *pszSQLCommand,
698 : OGRGeometry *poSpatialFilter,
699 : const char *pszDialect) override;
700 : virtual OGRErr AbortSQL() override;
701 : virtual void ReleaseResultSet(OGRLayer *poLayer) override;
702 :
703 : virtual const char *GetMetadataItem(const char *pszKey,
704 : const char *pszDomain) override;
705 :
706 : int UseCopy();
707 : void StartCopy(OGRPGTableLayer *poPGLayer);
708 : OGRErr EndCopy();
709 :
710 16 : bool IsUserTransactionActive()
711 : {
712 16 : return bUserTransactionActive;
713 : }
714 :
715 : bool CreateMetadataTableIfNeeded();
716 : bool HasOgrSystemTablesMetadataTable();
717 : bool HasWritePermissionsOnMetadataTable();
718 : };
719 :
720 : #endif /* ndef OGR_PG_H_INCLUDED */
|