1 /****************************************************************************** 2 * $Id: ogr_oci.h fa752ad6eabafaf630a704e1892a9d837d683cb3 2021-03-06 17:04:38 +0100 Even Rouault $ 3 * 4 * Project: Oracle Spatial Driver 5 * Purpose: Oracle Spatial OGR Driver Declarations. 6 * Author: Frank Warmerdam <warmerdam@pobox.com> 7 * 8 ****************************************************************************** 9 * Copyright (c) 2002, Frank Warmerdam <warmerdam@pobox.com> 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_OCI_H_INCLUDED 31 #define OGR_OCI_H_INCLUDED 32 33 #include "ogrsf_frmts.h" 34 #include "oci.h" 35 #include "cpl_error.h" 36 37 /* -------------------------------------------------------------------- */ 38 /* Low level Oracle spatial declarations. */ 39 /* -------------------------------------------------------------------- */ 40 #define TYPE_OWNER "MDSYS" 41 #define SDO_GEOMETRY "MDSYS.SDO_GEOMETRY" 42 43 typedef struct 44 { 45 OCINumber x; 46 OCINumber y; 47 OCINumber z; 48 } sdo_point_type; 49 50 typedef OCIArray sdo_elem_info_array; 51 typedef OCIArray sdo_ordinate_array; 52 53 typedef struct 54 { 55 OCINumber sdo_gtype; 56 OCINumber sdo_srid; 57 sdo_point_type sdo_point; 58 OCIArray *sdo_elem_info; 59 OCIArray *sdo_ordinates; 60 } SDO_GEOMETRY_TYPE; 61 62 typedef struct 63 { 64 OCIInd _atomic; 65 OCIInd x; 66 OCIInd y; 67 OCIInd z; 68 } sdo_point_type_ind; 69 70 typedef struct 71 { 72 OCIInd _atomic; 73 OCIInd sdo_gtype; 74 OCIInd sdo_srid; 75 sdo_point_type_ind sdo_point; 76 OCIInd sdo_elem_info; 77 OCIInd sdo_ordinates; 78 } SDO_GEOMETRY_ind; 79 80 #define ORA_GTYPE_MATCH(a,b) ( ((a) % 100) == ((b) % 100)) 81 #define ORA_GTYPE_UNKNOWN 0 82 #define ORA_GTYPE_POINT 1 83 #define ORA_GTYPE_LINESTRING 2 // or curve 84 #define ORA_GTYPE_POLYGON 3 // or surface 85 #define ORA_GTYPE_COLLECTION 4 86 #define ORA_GTYPE_MULTIPOINT 5 87 #define ORA_GTYPE_MULTILINESTRING 6 // or multicurve 88 #define ORA_GTYPE_MULTIPOLYGON 7 // or multisurface 89 #define ORA_GTYPE_SOLID 8 90 #define ORA_GTYPE_MULTISOLID 9 91 92 #define DEFAULT_STRING_SIZE 4000 93 94 /************************************************************************/ 95 /* OGROCISession */ 96 /************************************************************************/ 97 class CPL_DLL OGROCISession { 98 public: 99 OCIEnv *hEnv; 100 OCIError *hError; 101 OCISvcCtx *hSvcCtx; 102 OCIServer *hServer; 103 OCISession *hSession; 104 OCIDescribe*hDescribe; 105 OCIType *hGeometryTDO; 106 OCIType *hOrdinatesTDO; 107 OCIType *hElemInfoTDO; 108 109 char *pszUserid; 110 char *pszPassword; 111 char *pszDatabase; 112 113 public: 114 OGROCISession(); 115 virtual ~OGROCISession(); 116 117 int EstablishSession( const char *pszUserid, 118 const char *pszPassword, 119 const char *pszDatabase ); 120 121 int Failed( sword nStatus, const char *pszFunction = nullptr ); 122 123 CPLErr GetParamInfo( OCIParam *hParamDesc, OGRFieldDefn *poOGRDefn, 124 ub2 *pnOCIType, ub4 *pnOCILen ); 125 126 void CleanName( char * ); 127 128 OCIType *PinTDO( const char * ); 129 130 private: 131 132 int nServerVersion; 133 int nServerRelease; 134 size_t nMaxNameLength; 135 }; 136 137 OGROCISession CPL_DLL* 138 OGRGetOCISession( const char *pszUserid, 139 const char *pszPassword, 140 const char *pszDatabase ); 141 142 /************************************************************************/ 143 /* OGROCIStatement */ 144 /************************************************************************/ 145 class CPL_DLL OGROCIStatement { 146 public: 147 explicit OGROCIStatement( OGROCISession * ); 148 virtual ~OGROCIStatement(); 149 GetStatement()150 OCIStmt *GetStatement() { return hStatement; } 151 CPLErr BindScalar( const char *pszPlaceName, 152 void *pData, int nDataLen, int nSQLType, 153 sb2 *paeInd = nullptr ); 154 CPLErr BindString( const char *pszPlaceName, 155 const char *pszData, 156 sb2 *paeInd = nullptr ); 157 CPLErr BindObject( const char *pszPlaceName, void *pahObject, 158 OCIType *hTDO, void **papIndicators ); 159 160 char *pszCommandText; 161 162 CPLErr Prepare( const char * pszStatement ); 163 CPLErr Execute( const char * pszStatement, 164 int nMode = -1 ); 165 void Clean(); 166 GetResultDefn()167 OGRFeatureDefn *GetResultDefn() { return poDefn; } 168 169 char **SimpleFetchRow(); 170 GetAffectedRows()171 int GetAffectedRows() const { return nAffectedRows; } 172 173 private: 174 OGROCISession *poSession; 175 OCIStmt *hStatement; 176 177 OGRFeatureDefn*poDefn; 178 179 char **papszCurColumn; 180 char **papszCurImage; 181 sb2 *panCurColumnInd; 182 183 int nRawColumnCount; 184 int *panFieldMap; 185 int nAffectedRows; 186 }; 187 188 /************************************************************************/ 189 /* OGROCIStringBuf */ 190 /************************************************************************/ 191 class OGROCIStringBuf 192 { 193 char *pszString; 194 int nLen; 195 int nBufSize; 196 197 void UpdateEnd(); 198 199 public: 200 201 OGROCIStringBuf(); 202 ~OGROCIStringBuf(); 203 204 void MakeRoomFor( int ); 205 void Append( const char * ); 206 void Appendf( int nMax, const char *pszFormat, ... ) CPL_PRINT_FUNC_FORMAT (3, 4); 207 char *StealString(); 208 209 char GetLast(); GetEnd()210 char *GetEnd() { UpdateEnd(); return pszString + nLen; } GetString()211 char *GetString() { return pszString; } 212 213 void Clear(); 214 }; 215 216 /************************************************************************/ 217 /* OGROCILayer */ 218 /************************************************************************/ 219 220 class OGROCIDataSource; 221 222 class OGROCILayer CPL_NON_FINAL: public OGRLayer 223 { 224 protected: 225 OGRFeatureDefn *poFeatureDefn; 226 227 int iNextShapeId; 228 229 OGROCIDataSource *poDS; 230 231 char *pszQueryStatement; 232 233 int nResultOffset; 234 235 OGROCIStatement *poStatement; 236 237 int ExecuteQuery( const char * ); 238 239 SDO_GEOMETRY_TYPE *hLastGeom; 240 SDO_GEOMETRY_ind *hLastGeomInd; 241 242 char *pszGeomName; 243 int iGeomColumn; 244 245 char *pszFIDName; 246 int iFIDColumn; 247 248 OGRGeometry *TranslateGeometry(); 249 OGRGeometry *TranslateGeometryElement( int *piElement, 250 int nGType, int nDimension, 251 int nEType, 252 int nInterpretation, 253 int nStartOrdinal, 254 int nOrdCount); 255 int LoadElementInfo( int iElement, int nElemCount, int nTotalOrdCount, 256 int *pnEType, int *pnInterpretation, 257 int *pnStartOrdinal, int *pnElemOrdCount ); 258 int GetOrdinalPoint( int iOrdinal, int nDimension, 259 double *pdfX, double *pdfY, 260 double *pdfZ ); 261 262 public: 263 OGROCILayer(); 264 virtual ~OGROCILayer(); FindFieldIndex(const char * pszFieldName,int bExactMatch)265 virtual int FindFieldIndex( const char *pszFieldName, int bExactMatch ) override { return OGRLayer::FindFieldIndex( pszFieldName, bExactMatch ); } 266 267 virtual void ResetReading() override; 268 virtual OGRFeature *GetNextRawFeature(); 269 virtual OGRFeature *GetNextFeature() override; 270 GetLayerDefn()271 OGRFeatureDefn * GetLayerDefn() override { return poFeatureDefn; } 272 273 virtual int TestCapability( const char * ) override; 274 275 virtual const char *GetFIDColumn() override; 276 virtual const char *GetGeometryColumn() override; 277 278 int LookupTableSRID(); 279 }; 280 281 /************************************************************************/ 282 /* OGROCIWritableLayer */ 283 /************************************************************************/ 284 285 class OGROCIWritableLayer CPL_NON_FINAL: public OGROCILayer 286 { 287 protected: 288 int nDimension; 289 int nSRID; 290 291 int nOrdinalCount; 292 int nOrdinalMax; 293 double *padfOrdinals; 294 295 int nElemInfoCount; 296 int nElemInfoMax; 297 int *panElemInfo; 298 299 void PushOrdinal( double ); 300 void PushElemInfo( int, int, int ); 301 302 OGRErr TranslateToSDOGeometry( OGRGeometry *, 303 int *pnGType ); 304 OGRErr TranslateElementGroup( OGRGeometry *poGeometry ); 305 306 int bLaunderColumnNames; 307 int bPreservePrecision; 308 int nDefaultStringSize; 309 310 OGRSpatialReference *poSRS; 311 312 char **papszOptions; 313 314 int bTruncationReported; 315 void ReportTruncation( OGRFieldDefn * ); 316 317 void ParseDIMINFO( const char *, double *, double *, 318 double * ); 319 320 OGROCIWritableLayer(); 321 virtual ~OGROCIWritableLayer(); 322 public: 323 GetSpatialRef()324 virtual OGRSpatialReference *GetSpatialRef() override { return poSRS; } 325 virtual OGRErr CreateField( OGRFieldDefn *poField, 326 int bApproxOK = TRUE ) override; 327 virtual int FindFieldIndex( const char *pszFieldName, int bExactMatch ) override; 328 329 // following methods are not base class overrides 330 void SetOptions( char ** ); 331 332 void SetDimension( int ); SetLaunderFlag(int bFlag)333 void SetLaunderFlag( int bFlag ) 334 { bLaunderColumnNames = bFlag; } SetPrecisionFlag(int bFlag)335 void SetPrecisionFlag( int bFlag ) 336 { bPreservePrecision = bFlag; } SetDefaultStringSize(int nSize)337 void SetDefaultStringSize( int nSize ) 338 { nDefaultStringSize = nSize; } 339 }; 340 341 /************************************************************************/ 342 /* OGROCILoaderLayer */ 343 /************************************************************************/ 344 345 #define LDRM_UNKNOWN 0 346 #define LDRM_STREAM 1 347 #define LDRM_VARIABLE 2 348 #define LDRM_BINARY 3 349 350 class OGROCILoaderLayer final: public OGROCIWritableLayer 351 { 352 OGREnvelope sExtent; 353 int iNextFIDToWrite; 354 355 char *pszLoaderFilename; 356 357 FILE *fpLoader; 358 int bHeaderWritten; 359 360 FILE *fpData; 361 362 int nLDRMode; 363 364 void WriteLoaderHeader(); 365 void FinalizeNewLayer(); 366 367 OGRErr WriteFeatureStreamMode( OGRFeature * ); 368 OGRErr WriteFeatureVariableMode( OGRFeature * ); 369 // cppcheck-suppress functionStatic 370 OGRErr WriteFeatureBinaryMode( OGRFeature * ); 371 372 public: 373 OGROCILoaderLayer( OGROCIDataSource *, 374 const char * pszName, 375 const char *pszGeomCol, 376 int nSRID, 377 const char *pszLoaderFile ); 378 virtual ~OGROCILoaderLayer(); 379 380 virtual void ResetReading() override; 381 virtual GIntBig GetFeatureCount( int ) override; 382 SetSpatialFilter(OGRGeometry *)383 virtual void SetSpatialFilter( OGRGeometry * ) override {} SetSpatialFilter(int iGeomField,OGRGeometry * poGeom)384 virtual void SetSpatialFilter( int iGeomField, OGRGeometry *poGeom ) override 385 { OGRLayer::SetSpatialFilter(iGeomField, poGeom); } 386 SetAttributeFilter(const char *)387 virtual OGRErr SetAttributeFilter( const char * ) override 388 { return OGRERR_UNSUPPORTED_OPERATION; } 389 390 virtual OGRFeature *GetNextFeature() override; 391 392 virtual OGRErr ICreateFeature( OGRFeature *poFeature ) override; 393 GetSpatialRef()394 virtual OGRSpatialReference *GetSpatialRef() override { return poSRS; } 395 396 virtual int TestCapability( const char * ) override; 397 }; 398 399 /************************************************************************/ 400 /* OGROCITableLayer */ 401 /************************************************************************/ 402 403 class OGROCITableLayer final: public OGROCIWritableLayer 404 { 405 int bUpdateAccess; 406 int bNewLayer; 407 OGREnvelope sExtent; 408 bool bExtentUpdated; 409 410 int iNextFIDToWrite; 411 int bHaveSpatialIndex; 412 413 OGRFeatureDefn *ReadTableDefinition(const char *); 414 415 void BuildWhere(); 416 char *BuildFields(); 417 void BuildFullQueryStatement(); 418 419 char *pszQuery; 420 char *pszWHERE; 421 422 int bValidTable; 423 424 CPLString osTableName; 425 CPLString osOwner; 426 427 int nFirstId; 428 int nMultiLoadCount; 429 int bMultiLoad; 430 431 OCIArray *hOrdVARRAY; 432 OCIArray *hElemInfoVARRAY; 433 434 void UpdateLayerExtents(); 435 void CreateSpatialIndex(); 436 437 void TestForSpatialIndex( const char * ); 438 439 OGROCIStatement *poBoundStatement; 440 441 int nWriteCacheMax; 442 int nWriteCacheUsed; 443 444 SDO_GEOMETRY_TYPE *pasWriteGeoms; 445 SDO_GEOMETRY_TYPE **papsWriteGeomMap; 446 SDO_GEOMETRY_ind *pasWriteGeomInd; 447 SDO_GEOMETRY_ind **papsWriteGeomIndMap; 448 449 void **papWriteFields; 450 OCIInd **papaeWriteFieldInd; 451 int *panWriteFIDs; 452 453 int AllocAndBindForWrite(); 454 OGRErr FlushPendingFeatures(); 455 456 OGRErr UnboundCreateFeature( OGRFeature *poFeature ); 457 OGRErr BoundCreateFeature( OGRFeature *poFeature ); 458 459 public: 460 OGROCITableLayer( OGROCIDataSource *, 461 const char * pszName, OGRwkbGeometryType eGType, 462 int nSRID, int bUpdate, int bNew ); 463 virtual ~OGROCITableLayer(); 464 465 virtual void ResetReading() override; 466 virtual GIntBig GetFeatureCount( int ) override; 467 468 virtual void SetSpatialFilter( OGRGeometry * ) override; SetSpatialFilter(int iGeomField,OGRGeometry * poGeom)469 virtual void SetSpatialFilter( int iGeomField, OGRGeometry *poGeom ) override 470 { OGRLayer::SetSpatialFilter(iGeomField, poGeom); } 471 472 virtual OGRErr SetAttributeFilter( const char * ) override; 473 474 virtual OGRFeature *GetNextFeature() override; 475 virtual OGRFeature *GetFeature( GIntBig nFeatureId ) override; 476 477 virtual OGRErr ISetFeature( OGRFeature *poFeature ) override; 478 virtual OGRErr ICreateFeature( OGRFeature *poFeature ) override; 479 virtual OGRErr DeleteFeature( GIntBig nFID ) override; 480 481 virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce = TRUE) override; GetExtent(int iGeomField,OGREnvelope * psExtent,int bForce)482 virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent, int bForce) override 483 { return OGRLayer::GetExtent(iGeomField, psExtent, bForce); } 484 485 virtual int TestCapability( const char * ) override; 486 487 virtual OGRErr SyncToDisk() override; 488 489 // following methods are not base class overrides IsValid()490 int IsValid() { return bValidTable; } 491 492 int GetMaxFID(); 493 }; 494 495 /************************************************************************/ 496 /* OGROCISelectLayer */ 497 /************************************************************************/ 498 499 class OGROCISelectLayer final: public OGROCILayer 500 { 501 OGRFeatureDefn *ReadTableDefinition( OGROCIStatement * poStatement ); 502 503 public: 504 OGROCISelectLayer( OGROCIDataSource *, 505 const char * pszName, 506 OGROCIStatement *poStatement ); 507 ~OGROCISelectLayer(); 508 }; 509 510 /************************************************************************/ 511 /* OGROCIDataSource */ 512 /************************************************************************/ 513 514 class OGROCIDataSource final: public OGRDataSource 515 { 516 OGROCILayer **papoLayers; 517 int nLayers; 518 519 char *pszName; 520 char *pszDBName; 521 522 int bDSUpdate; 523 int bNoLogging; 524 525 OGROCISession *poSession; 526 527 // We maintain a list of known SRID to reduce the number of trips to 528 // the database to get SRSes. 529 int nKnownSRID; 530 int *panSRID; 531 OGRSpatialReference **papoSRS; 532 533 public: 534 OGROCIDataSource(); 535 virtual ~OGROCIDataSource(); 536 GetSession()537 OGROCISession *GetSession() { return poSession; } 538 539 int Open( const char *, char** papszOpenOptionsIn, 540 int bUpdate, int bTestOpen ); 541 int OpenTable( const char *pszTableName, 542 int nSRID, int bUpdate, int bTestOpen, 543 char** papszOpenOptionsIn ); 544 GetName()545 const char *GetName() override { return pszName; } GetLayerCount()546 int GetLayerCount() override { return nLayers; } 547 OGRLayer *GetLayer( int ) override; 548 OGRLayer *GetLayerByName(const char * pszName) override; 549 550 virtual OGRErr DeleteLayer(int) override; 551 virtual OGRLayer *ICreateLayer( const char *, 552 OGRSpatialReference * = nullptr, 553 OGRwkbGeometryType = wkbUnknown, 554 char ** = nullptr ) override; 555 556 int TestCapability( const char * ) override; 557 558 void DeleteLayer( const char * ); 559 560 void TruncateLayer( const char * ); 561 void ValidateLayer( const char * ); 562 563 virtual OGRLayer * ExecuteSQL( const char *pszSQLCommand, 564 OGRGeometry *poSpatialFilter, 565 const char *pszDialect ) override; 566 virtual void ReleaseResultSet( OGRLayer * poLayer ) override; 567 568 int FetchSRSId( OGRSpatialReference * poSRS ); 569 OGRSpatialReference *FetchSRS( int nSRID ); 570 }; 571 572 /* -------------------------------------------------------------------- */ 573 /* Helper functions. */ 574 /* -------------------------------------------------------------------- */ 575 int 576 OGROCIStrokeArcToOGRGeometry_Points( double dfStartX, double dfStartY, 577 double dfAlongX, double dfAlongY, 578 double dfEndX, double dfEndY, 579 double dfMaxAngleStepSizeDegrees, 580 int bForceWholeCircle, 581 OGRLineString *poLine ); 582 583 #endif /* ndef OGR_OCI_H_INCLUDED */ 584