1 : /******************************************************************************
2 : * $Id: ogr_pg.h 23565 2011-12-13 20:33:20Z 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,
75 : const char* pszFieldName);
76 : CPLString OGRPGEscapeColumnName(const char* pszColumnName);
77 :
78 : #define UNDETERMINED_SRID -2 /* Special value when we haven't yet looked for SRID */
79 :
80 : /************************************************************************/
81 : /* OGRPGLayer */
82 : /************************************************************************/
83 :
84 :
85 : class OGRPGDataSource;
86 :
87 : class OGRPGLayer : public OGRLayer
88 : {
89 : protected:
90 : OGRFeatureDefn *poFeatureDefn;
91 :
92 : // Layer spatial reference system, and srid.
93 : OGRSpatialReference *poSRS;
94 : int nSRSId;
95 : int nCoordDimension;
96 :
97 : int iNextShapeId;
98 :
99 : static char *GByteArrayToBYTEA( const GByte* pabyData, int nLen);
100 : static char *GeometryToBYTEA( OGRGeometry * );
101 : static GByte *BYTEAToGByteArray( const char *pszBytea, int* pnLength );
102 : static OGRGeometry *BYTEAToGeometry( const char * );
103 : static OGRGeometry *HEXToGeometry( const char * );
104 : static OGRGeometry *EWKBToGeometry( GByte* pabyWKB, int nLength );
105 : static char *GeometryToHex( OGRGeometry * poGeometry, int nSRSId );
106 : Oid GeometryToOID( OGRGeometry * );
107 : OGRGeometry *OIDToGeometry( Oid );
108 :
109 : OGRPGDataSource *poDS;
110 :
111 : char *pszQueryStatement;
112 :
113 : char *pszCursorName;
114 : PGresult *hCursorResult;
115 :
116 : int nResultOffset;
117 :
118 : int bHasWkb;
119 : int bWkbAsOid;
120 : int bHasPostGISGeometry;
121 : int bHasPostGISGeography;
122 : char *pszGeomColumn;
123 :
124 : int bHasFid;
125 : char *pszFIDColumn;
126 :
127 : int bCanUseBinaryCursor;
128 : int *panMapFieldNameToIndex;
129 :
130 : int ParsePGDate( const char *, OGRField * );
131 :
132 : void SetInitialQueryCursor();
133 : void CloseCursor();
134 :
135 : OGRErr RunGetExtentRequest( OGREnvelope *psExtent, int bForce,
136 : CPLString osCommand);
137 : void CreateMapFromFieldNameToIndex();
138 :
139 : OGRFeatureDefn *ReadResultDefinition(PGresult *hInitialResultIn);
140 :
141 : OGRFeature *RecordToFeature( int iRecord );
142 : OGRFeature *GetNextRawFeature();
143 :
144 : public:
145 : OGRPGLayer();
146 : virtual ~OGRPGLayer();
147 :
148 : virtual void ResetReading();
149 :
150 : virtual OGRFeatureDefn * GetLayerDefn();
151 :
152 : virtual OGRErr StartTransaction();
153 : virtual OGRErr CommitTransaction();
154 : virtual OGRErr RollbackTransaction();
155 :
156 : virtual OGRSpatialReference *GetSpatialRef();
157 :
158 : virtual const char *GetFIDColumn();
159 : virtual const char *GetGeometryColumn();
160 :
161 : virtual OGRErr SetNextByIndex( long nIndex );
162 : };
163 :
164 : /************************************************************************/
165 : /* OGRPGTableLayer */
166 : /************************************************************************/
167 :
168 : typedef enum
169 : {
170 : GEOM_TYPE_UNKNOWN = 0,
171 : GEOM_TYPE_GEOMETRY = 1,
172 : GEOM_TYPE_GEOGRAPHY = 2
173 : } PostgisType;
174 :
175 : class OGRPGTableLayer : public OGRPGLayer
176 : {
177 : int bUpdateAccess;
178 :
179 : OGRFeatureDefn *ReadTableDefinition();
180 :
181 : void BuildWhere(void);
182 : CPLString BuildFields(void);
183 : void BuildFullQueryStatement(void);
184 :
185 : char *pszTableName;
186 : char *pszSchemaName;
187 : char *pszSqlTableName;
188 :
189 : CPLString osPrimaryKey;
190 :
191 : int bGeometryInformationSet;
192 : OGRwkbGeometryType nGeomType;
193 :
194 : /* Name of the parent table with the geometry definition if it is a derived table or NULL */
195 : char *pszSqlGeomParentTableName;
196 :
197 : CPLString osDefnName;
198 :
199 : CPLString osQuery;
200 : CPLString osWHERE;
201 :
202 : int bLaunderColumnNames;
203 : int bPreservePrecision;
204 : int bUseCopy;
205 : int bCopyActive;
206 :
207 : OGRErr CreateFeatureViaCopy( OGRFeature *poFeature );
208 : OGRErr CreateFeatureViaInsert( OGRFeature *poFeature );
209 : CPLString BuildCopyFields(void);
210 :
211 : void AppendFieldValue(PGconn *hPGConn, CPLString& osCommand,
212 : OGRFeature* poFeature, int i);
213 :
214 : int bHasWarnedIncompatibleGeom;
215 : void CheckGeomTypeCompatibility(OGRGeometry* poGeom);
216 :
217 : int bRetrieveFID;
218 : int bHasWarnedAlreadySetFID;
219 :
220 : public:
221 : OGRPGTableLayer( OGRPGDataSource *,
222 : CPLString& osCurrentSchema,
223 : const char * pszTableName,
224 : const char * pszSchemaName,
225 : const char * pszGeomColumnIn,
226 : int bUpdate,
227 : int bAdvertizeGeomColumn,
228 : int nSRSId = UNDETERMINED_SRID );
229 : ~OGRPGTableLayer();
230 :
231 : void SetGeometryInformation(const char* pszGeomType,
232 : int nCoordDimension,
233 : int nSRID,
234 : PostgisType ePostgisType);
235 :
236 21011 : virtual const char *GetName() { return osDefnName.c_str(); }
237 : virtual OGRwkbGeometryType GetGeomType();
238 :
239 : virtual OGRFeatureDefn * GetLayerDefn();
240 :
241 : virtual OGRFeature *GetFeature( long nFeatureId );
242 : virtual void ResetReading();
243 : virtual OGRFeature *GetNextFeature();
244 : virtual int GetFeatureCount( int );
245 :
246 : virtual void SetSpatialFilter( OGRGeometry * );
247 :
248 : virtual OGRErr SetAttributeFilter( const char * );
249 :
250 : virtual OGRErr SetFeature( OGRFeature *poFeature );
251 : virtual OGRErr DeleteFeature( long nFID );
252 : virtual OGRErr CreateFeature( OGRFeature *poFeature );
253 :
254 : virtual OGRErr CreateField( OGRFieldDefn *poField,
255 : int bApproxOK = TRUE );
256 : virtual OGRErr DeleteField( int iField );
257 : virtual OGRErr AlterFieldDefn( int iField, OGRFieldDefn* poNewFieldDefn, int nFlags );
258 :
259 : virtual OGRSpatialReference *GetSpatialRef();
260 :
261 : virtual int TestCapability( const char * );
262 :
263 : virtual OGRErr GetExtent( OGREnvelope *psExtent, int bForce );
264 :
265 66 : const char* GetTableName() { return pszTableName; }
266 66 : const char* GetSchemaName() { return pszSchemaName; }
267 :
268 : // follow methods are not base class overrides
269 52 : void SetLaunderFlag( int bFlag )
270 52 : { bLaunderColumnNames = bFlag; }
271 52 : void SetPrecisionFlag( int bFlag )
272 52 : { bPreservePrecision = bFlag; }
273 :
274 : virtual OGRErr StartCopy();
275 : virtual OGRErr EndCopy();
276 :
277 : OGRFeatureDefn *GetLayerDefnCanReturnNULL();
278 : };
279 :
280 : /************************************************************************/
281 : /* OGRPGResultLayer */
282 : /************************************************************************/
283 :
284 : class OGRPGResultLayer : public OGRPGLayer
285 : {
286 : void BuildFullQueryStatement(void);
287 :
288 : char *pszRawStatement;
289 :
290 : CPLString osWHERE;
291 :
292 : public:
293 : OGRPGResultLayer( OGRPGDataSource *,
294 : const char * pszRawStatement,
295 : PGresult *hInitialResult );
296 : virtual ~OGRPGResultLayer();
297 :
298 : virtual void ResetReading();
299 : virtual int GetFeatureCount( int );
300 :
301 : virtual void SetSpatialFilter( OGRGeometry * );
302 :
303 : virtual OGRErr GetExtent( OGREnvelope *psExtent, int bForce );
304 :
305 : virtual int TestCapability( const char * );
306 :
307 : virtual OGRFeature *GetNextFeature();
308 : };
309 :
310 : /************************************************************************/
311 : /* OGRPGDataSource */
312 : /************************************************************************/
313 : class OGRPGDataSource : public OGRDataSource
314 : {
315 : typedef struct
316 : {
317 : int nMajor;
318 : int nMinor;
319 : int nRelease;
320 : } PGver;
321 :
322 : OGRPGTableLayer **papoLayers;
323 : int nLayers;
324 :
325 : char *pszName;
326 : char *pszDBName;
327 :
328 : int bDSUpdate;
329 : int bHavePostGIS;
330 : int bHaveGeography;
331 :
332 : int nSoftTransactionLevel;
333 :
334 : PGconn *hPGConn;
335 :
336 : int DeleteLayer( int iLayer );
337 :
338 : Oid nGeometryOID;
339 : Oid nGeographyOID;
340 :
341 : // We maintain a list of known SRID to reduce the number of trips to
342 : // the database to get SRSes.
343 : int nKnownSRID;
344 : int *panSRID;
345 : OGRSpatialReference **papoSRS;
346 :
347 : OGRPGTableLayer *poLayerInCopyMode;
348 :
349 : void OGRPGDecodeVersionString(PGver* psVersion, const char* pszVer);
350 :
351 : CPLString GetCurrentSchema();
352 :
353 : int nUndefinedSRID;
354 :
355 : public:
356 : PGver sPostgreSQLVersion;
357 : PGver sPostGISVersion;
358 :
359 : int bUseBinaryCursor;
360 : int bBinaryTimeFormatIsInt8;
361 :
362 4 : int GetUndefinedSRID() const { return nUndefinedSRID; }
363 :
364 : public:
365 : OGRPGDataSource();
366 : ~OGRPGDataSource();
367 :
368 14963 : PGconn *GetPGConn() { return hPGConn; }
369 :
370 : int FetchSRSId( OGRSpatialReference * poSRS );
371 : OGRSpatialReference *FetchSRS( int nSRSId );
372 : OGRErr InitializeMetadataTables();
373 :
374 : int Open( const char *, int bUpdate, int bTestOpen );
375 : OGRPGTableLayer* OpenTable( CPLString& osCurrentSchema,
376 : const char * pszTableName,
377 : const char * pszSchemaName,
378 : const char * pszGeomColumnIn,
379 : int bUpdate, int bTestOpen,
380 : int bAdvertizeGeomColumn );
381 :
382 96 : const char *GetName() { return pszName; }
383 239 : int GetLayerCount() { return nLayers; }
384 : OGRLayer *GetLayer( int );
385 : OGRLayer *GetLayerByName(const char * pszName);
386 :
387 : virtual OGRLayer *CreateLayer( const char *,
388 : OGRSpatialReference * = NULL,
389 : OGRwkbGeometryType = wkbUnknown,
390 : char ** = NULL );
391 :
392 : int TestCapability( const char * );
393 :
394 : OGRErr SoftStartTransaction();
395 : OGRErr SoftCommit();
396 : OGRErr SoftRollback();
397 :
398 : OGRErr FlushSoftTransaction();
399 :
400 200 : Oid GetGeometryOID() { return nGeometryOID; }
401 204 : Oid GetGeographyOID() { return nGeographyOID; }
402 :
403 : virtual OGRLayer * ExecuteSQL( const char *pszSQLCommand,
404 : OGRGeometry *poSpatialFilter,
405 : const char *pszDialect );
406 : virtual void ReleaseResultSet( OGRLayer * poLayer );
407 :
408 : char *LaunderName( const char * );
409 :
410 : int UseCopy();
411 : void StartCopy( OGRPGTableLayer *poPGLayer );
412 : OGRErr EndCopy( );
413 : int CopyInProgress( );
414 : };
415 :
416 : /************************************************************************/
417 : /* OGRPGDriver */
418 : /************************************************************************/
419 :
420 : class OGRPGDriver : public OGRSFDriver
421 178 : {
422 : public:
423 : ~OGRPGDriver();
424 :
425 : const char *GetName();
426 : OGRDataSource *Open( const char *, int );
427 :
428 : virtual OGRDataSource *CreateDataSource( const char *pszName,
429 : char ** = NULL );
430 :
431 : int TestCapability( const char * );
432 : };
433 :
434 : #endif /* ndef _OGR_PG_H_INCLUDED */
435 :
|