1 : /******************************************************************************
2 : * $Id: ogr_pg.h 25118 2012-10-13 22:38:33Z rouault $
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 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #ifndef _OGR_PG_H_INCLUDED
31 : #define _OGR_PG_H_INCLUDED
32 :
33 : #include "ogrsf_frmts.h"
34 : #include "libpq-fe.h"
35 : #include "cpl_string.h"
36 :
37 : #include "ogrpgutility.h"
38 :
39 : /* These are the OIDs for some builtin types, as returned by PQftype(). */
40 : /* They were copied from pg_type.h in src/include/catalog/pg_type.h */
41 :
42 : #define BOOLOID 16
43 : #define BYTEAOID 17
44 : #define CHAROID 18
45 : #define NAMEOID 19
46 : #define INT8OID 20
47 : #define INT2OID 21
48 : #define INT2VECTOROID 22
49 : #define INT4OID 23
50 : #define REGPROCOID 24
51 : #define TEXTOID 25
52 : #define OIDOID 26
53 : #define TIDOID 27
54 : #define XIDOID 28
55 : #define CIDOID 29
56 : #define OIDVECTOROID 30
57 : #define FLOAT4OID 700
58 : #define FLOAT8OID 701
59 : #define INT4ARRAYOID 1007
60 : #define TEXTARRAYOID 1009
61 : #define BPCHARARRAYOID 1014
62 : #define VARCHARARRAYOID 1015
63 : #define FLOAT4ARRAYOID 1021
64 : #define FLOAT8ARRAYOID 1022
65 : #define BPCHAROID 1042
66 : #define VARCHAROID 1043
67 : #define DATEOID 1082
68 : #define TIMEOID 1083
69 : #define TIMESTAMPOID 1114
70 : #define TIMESTAMPTZOID 1184
71 : #define NUMERICOID 1700
72 :
73 : CPLString OGRPGEscapeString(PGconn *hPGConn,
74 : const char* pszStrValue, int nMaxLength = -1,
75 : const char* pszTableName = "",
76 : const char* pszFieldName = "");
77 : CPLString OGRPGEscapeColumnName(const char* pszColumnName);
78 :
79 : #define UNDETERMINED_SRID -2 /* Special value when we haven't yet looked for SRID */
80 :
81 : /************************************************************************/
82 : /* OGRPGLayer */
83 : /************************************************************************/
84 :
85 :
86 : class OGRPGDataSource;
87 :
88 : class OGRPGLayer : public OGRLayer
89 : {
90 : protected:
91 : OGRFeatureDefn *poFeatureDefn;
92 :
93 : // Layer spatial reference system, and srid.
94 : OGRSpatialReference *poSRS;
95 : int nSRSId;
96 : int nCoordDimension;
97 :
98 : int iNextShapeId;
99 :
100 : static char *GByteArrayToBYTEA( const GByte* pabyData, int nLen);
101 : static char *GeometryToBYTEA( OGRGeometry * );
102 : static GByte *BYTEAToGByteArray( const char *pszBytea, int* pnLength );
103 : static OGRGeometry *BYTEAToGeometry( const char * );
104 : static OGRGeometry *HEXToGeometry( const char * );
105 : static OGRGeometry *EWKBToGeometry( GByte* pabyWKB, int nLength );
106 : static char *GeometryToHex( OGRGeometry * poGeometry, int nSRSId );
107 : Oid GeometryToOID( OGRGeometry * );
108 : OGRGeometry *OIDToGeometry( Oid );
109 :
110 : OGRPGDataSource *poDS;
111 :
112 : char *pszQueryStatement;
113 :
114 : char *pszCursorName;
115 : PGresult *hCursorResult;
116 :
117 : int nResultOffset;
118 :
119 : int bHasWkb;
120 : int bWkbAsOid;
121 : int bHasPostGISGeometry;
122 : int bHasPostGISGeography;
123 : char *pszGeomColumn;
124 :
125 : int bHasFid;
126 : char *pszFIDColumn;
127 :
128 : int bCanUseBinaryCursor;
129 : int *panMapFieldNameToIndex;
130 :
131 : int ParsePGDate( const char *, OGRField * );
132 :
133 : void SetInitialQueryCursor();
134 : void CloseCursor();
135 :
136 : OGRErr RunGetExtentRequest( OGREnvelope *psExtent, int bForce,
137 : CPLString osCommand);
138 : void CreateMapFromFieldNameToIndex();
139 :
140 : OGRFeatureDefn *ReadResultDefinition(PGresult *hInitialResultIn);
141 :
142 : OGRFeature *RecordToFeature( int iRecord );
143 : OGRFeature *GetNextRawFeature();
144 :
145 : public:
146 : OGRPGLayer();
147 : virtual ~OGRPGLayer();
148 :
149 : virtual void ResetReading();
150 :
151 : virtual OGRFeatureDefn * GetLayerDefn();
152 :
153 : virtual OGRErr StartTransaction();
154 : virtual OGRErr CommitTransaction();
155 : virtual OGRErr RollbackTransaction();
156 :
157 : virtual OGRSpatialReference *GetSpatialRef();
158 :
159 : virtual const char *GetFIDColumn();
160 : virtual const char *GetGeometryColumn();
161 :
162 : virtual OGRErr SetNextByIndex( long nIndex );
163 :
164 : int GetSRID();
165 : };
166 :
167 : /************************************************************************/
168 : /* OGRPGTableLayer */
169 : /************************************************************************/
170 :
171 : typedef enum
172 : {
173 : GEOM_TYPE_UNKNOWN = 0,
174 : GEOM_TYPE_GEOMETRY = 1,
175 : GEOM_TYPE_GEOGRAPHY = 2
176 : } PostgisType;
177 :
178 : class OGRPGTableLayer : public OGRPGLayer
179 : {
180 : int bUpdateAccess;
181 :
182 : OGRFeatureDefn *ReadTableDefinition();
183 :
184 : void BuildWhere(void);
185 : CPLString BuildFields(void);
186 : void BuildFullQueryStatement(void);
187 :
188 : char *pszTableName;
189 : char *pszSchemaName;
190 : char *pszSqlTableName;
191 :
192 : CPLString osPrimaryKey;
193 :
194 : int bGeometryInformationSet;
195 : OGRwkbGeometryType nGeomType;
196 :
197 : /* Name of the parent table with the geometry definition if it is a derived table or NULL */
198 : char *pszSqlGeomParentTableName;
199 :
200 : CPLString osDefnName;
201 :
202 : CPLString osQuery;
203 : CPLString osWHERE;
204 :
205 : int bLaunderColumnNames;
206 : int bPreservePrecision;
207 : int bUseCopy;
208 : int bCopyActive;
209 : int bFIDColumnInCopyFields;
210 :
211 : OGRErr CreateFeatureViaCopy( OGRFeature *poFeature );
212 : OGRErr CreateFeatureViaInsert( OGRFeature *poFeature );
213 : CPLString BuildCopyFields(int bSetFID);
214 :
215 : void AppendFieldValue(PGconn *hPGConn, CPLString& osCommand,
216 : OGRFeature* poFeature, int i);
217 :
218 : int bHasWarnedIncompatibleGeom;
219 : void CheckGeomTypeCompatibility(OGRGeometry* poGeom);
220 :
221 : int bRetrieveFID;
222 : int bHasWarnedAlreadySetFID;
223 :
224 : char **papszHSTOREColumns;
225 :
226 : public:
227 : OGRPGTableLayer( OGRPGDataSource *,
228 : CPLString& osCurrentSchema,
229 : const char * pszTableName,
230 : const char * pszSchemaName,
231 : const char * pszGeomColumnIn,
232 : int bUpdate,
233 : int bAdvertizeGeomColumn,
234 : int nSRSId = UNDETERMINED_SRID );
235 : ~OGRPGTableLayer();
236 :
237 : void SetGeometryInformation(const char* pszGeomType,
238 : int nCoordDimension,
239 : int nSRID,
240 : PostgisType ePostgisType);
241 :
242 72543 : virtual const char *GetName() { return osDefnName.c_str(); }
243 : virtual OGRwkbGeometryType GetGeomType();
244 :
245 : virtual OGRFeatureDefn * GetLayerDefn();
246 :
247 : virtual OGRFeature *GetFeature( long nFeatureId );
248 : virtual void ResetReading();
249 : virtual OGRFeature *GetNextFeature();
250 : virtual int GetFeatureCount( int );
251 :
252 : virtual void SetSpatialFilter( OGRGeometry * );
253 :
254 : virtual OGRErr SetAttributeFilter( const char * );
255 :
256 : virtual OGRErr SetFeature( OGRFeature *poFeature );
257 : virtual OGRErr DeleteFeature( long nFID );
258 : virtual OGRErr CreateFeature( OGRFeature *poFeature );
259 :
260 : virtual OGRErr CreateField( OGRFieldDefn *poField,
261 : int bApproxOK = TRUE );
262 : virtual OGRErr DeleteField( int iField );
263 : virtual OGRErr AlterFieldDefn( int iField, OGRFieldDefn* poNewFieldDefn, int nFlags );
264 :
265 : virtual OGRSpatialReference *GetSpatialRef();
266 :
267 : virtual int TestCapability( const char * );
268 :
269 : virtual OGRErr GetExtent( OGREnvelope *psExtent, int bForce );
270 :
271 71 : const char* GetTableName() { return pszTableName; }
272 71 : const char* GetSchemaName() { return pszSchemaName; }
273 :
274 : // follow methods are not base class overrides
275 55 : void SetLaunderFlag( int bFlag )
276 55 : { bLaunderColumnNames = bFlag; }
277 55 : void SetPrecisionFlag( int bFlag )
278 55 : { bPreservePrecision = bFlag; }
279 :
280 : void SetHSTOREColumns( const char* pszHSTOREColumns );
281 :
282 : virtual OGRErr StartCopy(int bSetFID);
283 : virtual OGRErr EndCopy();
284 :
285 : OGRFeatureDefn *GetLayerDefnCanReturnNULL();
286 : };
287 :
288 : /************************************************************************/
289 : /* OGRPGResultLayer */
290 : /************************************************************************/
291 :
292 : class OGRPGResultLayer : public OGRPGLayer
293 : {
294 : void BuildFullQueryStatement(void);
295 :
296 : char *pszRawStatement;
297 :
298 : char *pszGeomTableName;
299 : char *pszGeomTableSchemaName;
300 :
301 : CPLString osWHERE;
302 :
303 : public:
304 : OGRPGResultLayer( OGRPGDataSource *,
305 : const char * pszRawStatement,
306 : PGresult *hInitialResult );
307 : virtual ~OGRPGResultLayer();
308 :
309 : virtual void ResetReading();
310 : virtual int GetFeatureCount( int );
311 :
312 : virtual void SetSpatialFilter( OGRGeometry * );
313 :
314 : virtual OGRErr GetExtent( OGREnvelope *psExtent, int bForce );
315 :
316 : virtual int TestCapability( const char * );
317 :
318 : virtual OGRFeature *GetNextFeature();
319 :
320 : virtual OGRSpatialReference *GetSpatialRef();
321 : };
322 :
323 : /************************************************************************/
324 : /* OGRPGDataSource */
325 : /************************************************************************/
326 : class OGRPGDataSource : public OGRDataSource
327 : {
328 : typedef struct
329 : {
330 : int nMajor;
331 : int nMinor;
332 : int nRelease;
333 : } PGver;
334 :
335 : OGRPGTableLayer **papoLayers;
336 : int nLayers;
337 :
338 : char *pszName;
339 : char *pszDBName;
340 :
341 : int bDSUpdate;
342 : int bHavePostGIS;
343 : int bHaveGeography;
344 :
345 : int nSoftTransactionLevel;
346 :
347 : PGconn *hPGConn;
348 :
349 : int DeleteLayer( int iLayer );
350 :
351 : Oid nGeometryOID;
352 : Oid nGeographyOID;
353 :
354 : // We maintain a list of known SRID to reduce the number of trips to
355 : // the database to get SRSes.
356 : int nKnownSRID;
357 : int *panSRID;
358 : OGRSpatialReference **papoSRS;
359 :
360 : OGRPGTableLayer *poLayerInCopyMode;
361 :
362 : void OGRPGDecodeVersionString(PGver* psVersion, const char* pszVer);
363 :
364 : CPLString osCurrentSchema;
365 : CPLString GetCurrentSchema();
366 :
367 : int nUndefinedSRID;
368 :
369 : public:
370 : PGver sPostgreSQLVersion;
371 : PGver sPostGISVersion;
372 :
373 : int bUseBinaryCursor;
374 : int bBinaryTimeFormatIsInt8;
375 : int bUseEscapeStringSyntax;
376 :
377 4 : int GetUndefinedSRID() const { return nUndefinedSRID; }
378 :
379 : public:
380 : OGRPGDataSource();
381 : ~OGRPGDataSource();
382 :
383 27962 : PGconn *GetPGConn() { return hPGConn; }
384 :
385 : int FetchSRSId( OGRSpatialReference * poSRS );
386 : OGRSpatialReference *FetchSRS( int nSRSId );
387 : OGRErr InitializeMetadataTables();
388 :
389 : int Open( const char *, int bUpdate, int bTestOpen );
390 : OGRPGTableLayer* OpenTable( CPLString& osCurrentSchema,
391 : const char * pszTableName,
392 : const char * pszSchemaName,
393 : const char * pszGeomColumnIn,
394 : int bUpdate, int bTestOpen,
395 : int bAdvertizeGeomColumn );
396 :
397 103 : const char *GetName() { return pszName; }
398 279 : int GetLayerCount() { return nLayers; }
399 : OGRLayer *GetLayer( int );
400 : OGRLayer *GetLayerByName(const char * pszName);
401 :
402 : virtual OGRLayer *CreateLayer( const char *,
403 : OGRSpatialReference * = NULL,
404 : OGRwkbGeometryType = wkbUnknown,
405 : char ** = NULL );
406 :
407 : int TestCapability( const char * );
408 :
409 : OGRErr SoftStartTransaction();
410 : OGRErr SoftCommit();
411 : OGRErr SoftRollback();
412 :
413 : OGRErr FlushSoftTransaction();
414 :
415 233 : Oid GetGeometryOID() { return nGeometryOID; }
416 237 : Oid GetGeographyOID() { return nGeographyOID; }
417 :
418 : virtual OGRLayer * ExecuteSQL( const char *pszSQLCommand,
419 : OGRGeometry *poSpatialFilter,
420 : const char *pszDialect );
421 : virtual void ReleaseResultSet( OGRLayer * poLayer );
422 :
423 : char *LaunderName( const char * );
424 :
425 : int UseCopy();
426 : void StartCopy( OGRPGTableLayer *poPGLayer );
427 : OGRErr EndCopy( );
428 : int CopyInProgress( );
429 : };
430 :
431 : /************************************************************************/
432 : /* OGRPGDriver */
433 : /************************************************************************/
434 :
435 : class OGRPGDriver : public OGRSFDriver
436 226 : {
437 : public:
438 : ~OGRPGDriver();
439 :
440 : const char *GetName();
441 : OGRDataSource *Open( const char *, int );
442 :
443 : virtual OGRDataSource *CreateDataSource( const char *pszName,
444 : char ** = NULL );
445 :
446 : int TestCapability( const char * );
447 : };
448 :
449 : #endif /* ndef _OGR_PG_H_INCLUDED */
450 :
|