1 : /******************************************************************************
2 : * $Id: ogr_pg.h 17984 2009-11-10 11:42:01Z 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 : #ifdef DEBUG
38 : PGresult *OGRPG_PQexec_dbg(PGconn *conn, const char *query);
39 : #define PQexec OGRPG_PQexec_dbg
40 : #endif
41 :
42 : /* These are the OIDs for some builtin types, as returned by PQftype(). */
43 : /* They were copied from pg_type.h in src/include/catalog/pg_type.h */
44 :
45 : #define BOOLOID 16
46 : #define BYTEAOID 17
47 : #define CHAROID 18
48 : #define NAMEOID 19
49 : #define INT8OID 20
50 : #define INT2OID 21
51 : #define INT2VECTOROID 22
52 : #define INT4OID 23
53 : #define REGPROCOID 24
54 : #define TEXTOID 25
55 : #define OIDOID 26
56 : #define TIDOID 27
57 : #define XIDOID 28
58 : #define CIDOID 29
59 : #define OIDVECTOROID 30
60 : #define FLOAT4OID 700
61 : #define FLOAT8OID 701
62 : #define INT4ARRAYOID 1007
63 : #define TEXTARRAYOID 1009
64 : #define BPCHARARRAYOID 1014
65 : #define VARCHARARRAYOID 1015
66 : #define FLOAT4ARRAYOID 1021
67 : #define FLOAT8ARRAYOID 1022
68 : #define BPCHAROID 1042
69 : #define VARCHAROID 1043
70 : #define DATEOID 1082
71 : #define TIMEOID 1083
72 : #define TIMESTAMPOID 1114
73 : #define TIMESTAMPTZOID 1184
74 : #define NUMERICOID 1700
75 :
76 : /************************************************************************/
77 : /* OGRPGLayer */
78 : /************************************************************************/
79 :
80 :
81 : class OGRPGDataSource;
82 :
83 : class OGRPGLayer : public OGRLayer
84 : {
85 : protected:
86 : OGRFeatureDefn *poFeatureDefn;
87 :
88 : // Layer spatial reference system, and srid.
89 : OGRSpatialReference *poSRS;
90 : int nSRSId;
91 : int nCoordDimension;
92 :
93 : int iNextShapeId;
94 :
95 : static char *GByteArrayToBYTEA( const GByte* pabyData, int nLen);
96 : static char *GeometryToBYTEA( OGRGeometry * );
97 : static GByte *BYTEAToGByteArray( const char *pszBytea, int* pnLength );
98 : static OGRGeometry *BYTEAToGeometry( const char * );
99 : static OGRGeometry *HEXToGeometry( const char * );
100 : static OGRGeometry *EWKBToGeometry( GByte* pabyWKB, int nLength );
101 : static char *GeometryToHex( OGRGeometry * poGeometry, int nSRSId );
102 : Oid GeometryToOID( OGRGeometry * );
103 : OGRGeometry *OIDToGeometry( Oid );
104 :
105 : OGRPGDataSource *poDS;
106 :
107 : char *pszQueryStatement;
108 :
109 : char *pszCursorName;
110 : PGresult *hCursorResult;
111 : int bCursorActive;
112 :
113 : int nResultOffset;
114 :
115 : int bHasWkb;
116 : int bWkbAsOid;
117 : int bHasPostGISGeometry;
118 : int bHasPostGISGeography;
119 : char *pszGeomColumn;
120 :
121 : int bHasFid;
122 : char *pszFIDColumn;
123 :
124 : int bCanUseBinaryCursor;
125 : int *panMapFieldNameToIndex;
126 :
127 : int ParsePGDate( const char *, OGRField * );
128 :
129 : void SetInitialQueryCursor();
130 :
131 : OGRErr RunGetExtentRequest( OGREnvelope *psExtent, int bForce,
132 : CPLString osCommand);
133 : void CreateMapFromFieldNameToIndex();
134 :
135 : public:
136 : OGRPGLayer();
137 : virtual ~OGRPGLayer();
138 :
139 : virtual void ResetReading();
140 :
141 1844 : OGRFeatureDefn * GetLayerDefn() { return poFeatureDefn; }
142 :
143 : virtual OGRErr StartTransaction();
144 : virtual OGRErr CommitTransaction();
145 : virtual OGRErr RollbackTransaction();
146 :
147 : virtual OGRSpatialReference *GetSpatialRef();
148 :
149 : virtual const char *GetFIDColumn();
150 : virtual const char *GetGeometryColumn();
151 :
152 : virtual OGRErr SetNextByIndex( long nIndex );
153 :
154 : /* custom methods */
155 : virtual OGRFeature *RecordToFeature( int iRecord );
156 : virtual OGRFeature *GetNextRawFeature();
157 : };
158 :
159 : /************************************************************************/
160 : /* OGRPGTableLayer */
161 : /************************************************************************/
162 :
163 :
164 : class OGRPGTableLayer : public OGRPGLayer
165 : {
166 : int bUpdateAccess;
167 :
168 : OGRFeatureDefn *ReadTableDefinition(CPLString& osCurrentSchema,
169 : const char * pszTableName,
170 : const char * pszSchemaName,
171 : const char * pszGeomColumnIn,
172 : int bAdvertizeGeomColumn);
173 :
174 : void BuildWhere(void);
175 : CPLString BuildFields(void);
176 : void BuildFullQueryStatement(void);
177 :
178 : char *pszTableName;
179 : char *pszSchemaName;
180 : char *pszSqlTableName;
181 :
182 : /* Name of the parent table with the geometry definition if it is a derived table or NULL */
183 : char *pszSqlGeomParentTableName;
184 :
185 : CPLString osQuery;
186 : CPLString osWHERE;
187 :
188 : int bLaunderColumnNames;
189 : int bPreservePrecision;
190 : int bUseCopy;
191 : int bCopyActive;
192 :
193 : OGRErr CreateFeatureViaCopy( OGRFeature *poFeature );
194 : OGRErr CreateFeatureViaInsert( OGRFeature *poFeature );
195 : CPLString BuildCopyFields(void);
196 :
197 : void AppendFieldValue(PGconn *hPGConn, CPLString& osCommand,
198 : OGRFeature* poFeature, int i);
199 :
200 : int bHasWarnedIncompatibleGeom;
201 : void CheckGeomTypeCompatibility(OGRGeometry* poGeom);
202 :
203 : public:
204 : OGRPGTableLayer( OGRPGDataSource *,
205 : CPLString& osCurrentSchema,
206 : const char * pszTableName,
207 : const char * pszSchemaName,
208 : const char * pszGeomColumnIn,
209 : int bUpdate,
210 : int bAdvertizeGeomColumn,
211 : int nSRSId = -2 );
212 : ~OGRPGTableLayer();
213 :
214 : virtual OGRFeature *GetFeature( long nFeatureId );
215 : virtual void ResetReading();
216 : virtual OGRFeature *GetNextFeature();
217 : virtual int GetFeatureCount( int );
218 :
219 : virtual void SetSpatialFilter( OGRGeometry * );
220 :
221 : virtual OGRErr SetAttributeFilter( const char * );
222 :
223 : virtual OGRErr SetFeature( OGRFeature *poFeature );
224 : virtual OGRErr DeleteFeature( long nFID );
225 : virtual OGRErr CreateFeature( OGRFeature *poFeature );
226 :
227 : virtual OGRErr CreateField( OGRFieldDefn *poField,
228 : int bApproxOK = TRUE );
229 :
230 : virtual OGRSpatialReference *GetSpatialRef();
231 :
232 : virtual int TestCapability( const char * );
233 :
234 : virtual OGRErr GetExtent( OGREnvelope *psExtent, int bForce );
235 :
236 37 : const char* GetTableName() { return pszTableName; }
237 37 : const char* GetSchemaName() { return pszSchemaName; }
238 :
239 : // follow methods are not base class overrides
240 30 : void SetLaunderFlag( int bFlag )
241 30 : { bLaunderColumnNames = bFlag; }
242 30 : void SetPrecisionFlag( int bFlag )
243 30 : { bPreservePrecision = bFlag; }
244 :
245 : virtual OGRErr StartCopy();
246 : virtual OGRErr EndCopy();
247 : };
248 :
249 : /************************************************************************/
250 : /* OGRPGResultLayer */
251 : /************************************************************************/
252 :
253 : class OGRPGResultLayer : public OGRPGLayer
254 : {
255 : void BuildFullQueryStatement(void);
256 :
257 : char *pszRawStatement;
258 :
259 : CPLString osWHERE;
260 :
261 : OGRFeatureDefn *ReadResultDefinition(PGresult *hInitialResultIn);
262 :
263 : public:
264 : OGRPGResultLayer( OGRPGDataSource *,
265 : const char * pszRawStatement,
266 : PGresult *hInitialResult );
267 : virtual ~OGRPGResultLayer();
268 :
269 : virtual void ResetReading();
270 : virtual int GetFeatureCount( int );
271 :
272 : virtual void SetSpatialFilter( OGRGeometry * );
273 :
274 : virtual OGRErr GetExtent( OGREnvelope *psExtent, int bForce );
275 :
276 : virtual int TestCapability( const char * );
277 :
278 : virtual OGRFeature *GetNextFeature();
279 : };
280 :
281 : /************************************************************************/
282 : /* OGRPGDataSource */
283 : /************************************************************************/
284 : class OGRPGDataSource : public OGRDataSource
285 : {
286 : typedef struct
287 : {
288 : int nMajor;
289 : int nMinor;
290 : int nRelease;
291 : } PGver;
292 :
293 : OGRPGTableLayer **papoLayers;
294 : int nLayers;
295 :
296 : char *pszName;
297 : char *pszDBName;
298 :
299 : int bDSUpdate;
300 : int bHavePostGIS;
301 : int bHaveGeography;
302 :
303 : int nSoftTransactionLevel;
304 :
305 : PGconn *hPGConn;
306 :
307 : int DeleteLayer( int iLayer );
308 :
309 : Oid nGeometryOID;
310 : Oid nGeographyOID;
311 :
312 : // We maintain a list of known SRID to reduce the number of trips to
313 : // the database to get SRSes.
314 : int nKnownSRID;
315 : int *panSRID;
316 : OGRSpatialReference **papoSRS;
317 :
318 : OGRPGTableLayer *poLayerInCopyMode;
319 :
320 : void OGRPGDecodeVersionString(PGver* psVersion, char* pszVer);
321 :
322 : CPLString GetCurrentSchema();
323 :
324 : public:
325 : PGver sPostgreSQLVersion;
326 : PGver sPostGISVersion;
327 :
328 : int bUseBinaryCursor;
329 : int bBinaryTimeFormatIsInt8;
330 :
331 : public:
332 : OGRPGDataSource();
333 : ~OGRPGDataSource();
334 :
335 9102 : PGconn *GetPGConn() { return hPGConn; }
336 :
337 : int FetchSRSId( OGRSpatialReference * poSRS );
338 : OGRSpatialReference *FetchSRS( int nSRSId );
339 : OGRErr InitializeMetadataTables();
340 :
341 : int Open( const char *, int bUpdate, int bTestOpen );
342 : int OpenTable( CPLString& osCurrentSchema,
343 : const char * pszTableName,
344 : const char * pszSchemaName,
345 : const char * pszGeomColumnIn,
346 : int bUpdate, int bTestOpen,
347 : int bAdvertizeGeomColumn );
348 :
349 53 : const char *GetName() { return pszName; }
350 121 : int GetLayerCount() { return nLayers; }
351 : OGRLayer *GetLayer( int );
352 : OGRLayer *GetLayerByName(const char * pszName);
353 :
354 : virtual OGRLayer *CreateLayer( const char *,
355 : OGRSpatialReference * = NULL,
356 : OGRwkbGeometryType = wkbUnknown,
357 : char ** = NULL );
358 :
359 : int TestCapability( const char * );
360 :
361 : OGRErr SoftStartTransaction();
362 : OGRErr SoftCommit();
363 : OGRErr SoftRollback();
364 :
365 : OGRErr FlushSoftTransaction();
366 :
367 143 : Oid GetGeometryOID() { return nGeometryOID; }
368 143 : Oid GetGeographyOID() { return nGeographyOID; }
369 :
370 : virtual OGRLayer * ExecuteSQL( const char *pszSQLCommand,
371 : OGRGeometry *poSpatialFilter,
372 : const char *pszDialect );
373 : virtual void ReleaseResultSet( OGRLayer * poLayer );
374 :
375 : char *LaunderName( const char * );
376 :
377 : int UseCopy();
378 : void StartCopy( OGRPGTableLayer *poPGLayer );
379 : OGRErr EndCopy( );
380 : int CopyInProgress( );
381 : };
382 :
383 : /************************************************************************/
384 : /* OGRPGDriver */
385 : /************************************************************************/
386 :
387 : class OGRPGDriver : public OGRSFDriver
388 64 : {
389 : public:
390 : ~OGRPGDriver();
391 :
392 : const char *GetName();
393 : OGRDataSource *Open( const char *, int );
394 :
395 : virtual OGRDataSource *CreateDataSource( const char *pszName,
396 : char ** = NULL );
397 :
398 : int TestCapability( const char * );
399 : };
400 :
401 : #endif /* ndef _OGR_PG_H_INCLUDED */
402 :
|