1 : /******************************************************************************
2 : * $Id: ogr_pg.h 19242 2010-03-28 19:30:21Z 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 : CPLString OGRPGEscapeString(PGconn *hPGConn,
77 : const char* pszStrValue, int nMaxLength,
78 : const char* pszFieldName);
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 : int bCursorActive;
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 :
135 : OGRErr RunGetExtentRequest( OGREnvelope *psExtent, int bForce,
136 : CPLString osCommand);
137 : void CreateMapFromFieldNameToIndex();
138 :
139 : public:
140 : OGRPGLayer();
141 : virtual ~OGRPGLayer();
142 :
143 : virtual void ResetReading();
144 :
145 7552 : OGRFeatureDefn * GetLayerDefn() { return poFeatureDefn; }
146 :
147 : virtual OGRErr StartTransaction();
148 : virtual OGRErr CommitTransaction();
149 : virtual OGRErr RollbackTransaction();
150 :
151 : virtual OGRSpatialReference *GetSpatialRef();
152 :
153 : virtual const char *GetFIDColumn();
154 : virtual const char *GetGeometryColumn();
155 :
156 : virtual OGRErr SetNextByIndex( long nIndex );
157 :
158 : /* custom methods */
159 : virtual OGRFeature *RecordToFeature( int iRecord );
160 : virtual OGRFeature *GetNextRawFeature();
161 : };
162 :
163 : /************************************************************************/
164 : /* OGRPGTableLayer */
165 : /************************************************************************/
166 :
167 :
168 : class OGRPGTableLayer : public OGRPGLayer
169 : {
170 : int bUpdateAccess;
171 :
172 : OGRFeatureDefn *ReadTableDefinition(CPLString& osCurrentSchema,
173 : const char * pszTableName,
174 : const char * pszSchemaName,
175 : const char * pszGeomColumnIn,
176 : int bAdvertizeGeomColumn);
177 :
178 : void BuildWhere(void);
179 : CPLString BuildFields(void);
180 : void BuildFullQueryStatement(void);
181 :
182 : char *pszTableName;
183 : char *pszSchemaName;
184 : char *pszSqlTableName;
185 :
186 : /* Name of the parent table with the geometry definition if it is a derived table or NULL */
187 : char *pszSqlGeomParentTableName;
188 :
189 : CPLString osQuery;
190 : CPLString osWHERE;
191 :
192 : int bLaunderColumnNames;
193 : int bPreservePrecision;
194 : int bUseCopy;
195 : int bCopyActive;
196 :
197 : OGRErr CreateFeatureViaCopy( OGRFeature *poFeature );
198 : OGRErr CreateFeatureViaInsert( OGRFeature *poFeature );
199 : CPLString BuildCopyFields(void);
200 :
201 : void AppendFieldValue(PGconn *hPGConn, CPLString& osCommand,
202 : OGRFeature* poFeature, int i);
203 :
204 : int bHasWarnedIncompatibleGeom;
205 : void CheckGeomTypeCompatibility(OGRGeometry* poGeom);
206 :
207 : public:
208 : OGRPGTableLayer( OGRPGDataSource *,
209 : CPLString& osCurrentSchema,
210 : const char * pszTableName,
211 : const char * pszSchemaName,
212 : const char * pszGeomColumnIn,
213 : int bUpdate,
214 : int bAdvertizeGeomColumn,
215 : int nSRSId = -2 );
216 : ~OGRPGTableLayer();
217 :
218 : virtual OGRFeature *GetFeature( long nFeatureId );
219 : virtual void ResetReading();
220 : virtual OGRFeature *GetNextFeature();
221 : virtual int GetFeatureCount( int );
222 :
223 : virtual void SetSpatialFilter( OGRGeometry * );
224 :
225 : virtual OGRErr SetAttributeFilter( const char * );
226 :
227 : virtual OGRErr SetFeature( OGRFeature *poFeature );
228 : virtual OGRErr DeleteFeature( long nFID );
229 : virtual OGRErr CreateFeature( OGRFeature *poFeature );
230 :
231 : virtual OGRErr CreateField( OGRFieldDefn *poField,
232 : int bApproxOK = TRUE );
233 :
234 : virtual OGRSpatialReference *GetSpatialRef();
235 :
236 : virtual int TestCapability( const char * );
237 :
238 : virtual OGRErr GetExtent( OGREnvelope *psExtent, int bForce );
239 :
240 46 : const char* GetTableName() { return pszTableName; }
241 46 : const char* GetSchemaName() { return pszSchemaName; }
242 :
243 : // follow methods are not base class overrides
244 35 : void SetLaunderFlag( int bFlag )
245 35 : { bLaunderColumnNames = bFlag; }
246 35 : void SetPrecisionFlag( int bFlag )
247 35 : { bPreservePrecision = bFlag; }
248 :
249 : virtual OGRErr StartCopy();
250 : virtual OGRErr EndCopy();
251 : };
252 :
253 : /************************************************************************/
254 : /* OGRPGResultLayer */
255 : /************************************************************************/
256 :
257 : class OGRPGResultLayer : public OGRPGLayer
258 : {
259 : void BuildFullQueryStatement(void);
260 :
261 : char *pszRawStatement;
262 :
263 : CPLString osWHERE;
264 :
265 : OGRFeatureDefn *ReadResultDefinition(PGresult *hInitialResultIn);
266 :
267 : public:
268 : OGRPGResultLayer( OGRPGDataSource *,
269 : const char * pszRawStatement,
270 : PGresult *hInitialResult );
271 : virtual ~OGRPGResultLayer();
272 :
273 : virtual void ResetReading();
274 : virtual int GetFeatureCount( int );
275 :
276 : virtual void SetSpatialFilter( OGRGeometry * );
277 :
278 : virtual OGRErr GetExtent( OGREnvelope *psExtent, int bForce );
279 :
280 : virtual int TestCapability( const char * );
281 :
282 : virtual OGRFeature *GetNextFeature();
283 : };
284 :
285 : /************************************************************************/
286 : /* OGRPGDataSource */
287 : /************************************************************************/
288 : class OGRPGDataSource : public OGRDataSource
289 : {
290 : typedef struct
291 : {
292 : int nMajor;
293 : int nMinor;
294 : int nRelease;
295 : } PGver;
296 :
297 : OGRPGTableLayer **papoLayers;
298 : int nLayers;
299 :
300 : char *pszName;
301 : char *pszDBName;
302 :
303 : int bDSUpdate;
304 : int bHavePostGIS;
305 : int bHaveGeography;
306 :
307 : int nSoftTransactionLevel;
308 :
309 : PGconn *hPGConn;
310 :
311 : int DeleteLayer( int iLayer );
312 :
313 : Oid nGeometryOID;
314 : Oid nGeographyOID;
315 :
316 : // We maintain a list of known SRID to reduce the number of trips to
317 : // the database to get SRSes.
318 : int nKnownSRID;
319 : int *panSRID;
320 : OGRSpatialReference **papoSRS;
321 :
322 : OGRPGTableLayer *poLayerInCopyMode;
323 :
324 : void OGRPGDecodeVersionString(PGver* psVersion, char* pszVer);
325 :
326 : CPLString GetCurrentSchema();
327 :
328 : public:
329 : PGver sPostgreSQLVersion;
330 : PGver sPostGISVersion;
331 :
332 : int bUseBinaryCursor;
333 : int bBinaryTimeFormatIsInt8;
334 :
335 : public:
336 : OGRPGDataSource();
337 : ~OGRPGDataSource();
338 :
339 12858 : PGconn *GetPGConn() { return hPGConn; }
340 :
341 : int FetchSRSId( OGRSpatialReference * poSRS );
342 : OGRSpatialReference *FetchSRS( int nSRSId );
343 : OGRErr InitializeMetadataTables();
344 :
345 : int Open( const char *, int bUpdate, int bTestOpen );
346 : int OpenTable( CPLString& osCurrentSchema,
347 : const char * pszTableName,
348 : const char * pszSchemaName,
349 : const char * pszGeomColumnIn,
350 : int bUpdate, int bTestOpen,
351 : int bAdvertizeGeomColumn );
352 :
353 58 : const char *GetName() { return pszName; }
354 167 : int GetLayerCount() { return nLayers; }
355 : OGRLayer *GetLayer( int );
356 : OGRLayer *GetLayerByName(const char * pszName);
357 :
358 : virtual OGRLayer *CreateLayer( const char *,
359 : OGRSpatialReference * = NULL,
360 : OGRwkbGeometryType = wkbUnknown,
361 : char ** = NULL );
362 :
363 : int TestCapability( const char * );
364 :
365 : OGRErr SoftStartTransaction();
366 : OGRErr SoftCommit();
367 : OGRErr SoftRollback();
368 :
369 : OGRErr FlushSoftTransaction();
370 :
371 154 : Oid GetGeometryOID() { return nGeometryOID; }
372 154 : Oid GetGeographyOID() { return nGeographyOID; }
373 :
374 : virtual OGRLayer * ExecuteSQL( const char *pszSQLCommand,
375 : OGRGeometry *poSpatialFilter,
376 : const char *pszDialect );
377 : virtual void ReleaseResultSet( OGRLayer * poLayer );
378 :
379 : char *LaunderName( const char * );
380 :
381 : int UseCopy();
382 : void StartCopy( OGRPGTableLayer *poPGLayer );
383 : OGRErr EndCopy( );
384 : int CopyInProgress( );
385 : };
386 :
387 : /************************************************************************/
388 : /* OGRPGDriver */
389 : /************************************************************************/
390 :
391 : class OGRPGDriver : public OGRSFDriver
392 80 : {
393 : public:
394 : ~OGRPGDriver();
395 :
396 : const char *GetName();
397 : OGRDataSource *Open( const char *, int );
398 :
399 : virtual OGRDataSource *CreateDataSource( const char *pszName,
400 : char ** = NULL );
401 :
402 : int TestCapability( const char * );
403 : };
404 :
405 : #endif /* ndef _OGR_PG_H_INCLUDED */
406 :
|